[Gmsh] If () Endif issues

Danny Holstein dgholstein at embarqmail.com
Wed Mar 25 15:19:27 CET 2015


Thanks so much, that worked like a charm!

Is there the equivalent of the Point{} function for Line, to get the point indices for a line?  The more scripting I do, the more I like to pass off the work to functions.

BTW:  The following script are my functions to radius corners and to construct a DXF drawing, I hope someone can get use from it:

// 
// radiusing corners
// Author:	Danny Holstein
// Started:	2/12/15
// 
// Function radius_corner(aL, bL, aR, bR, r) 
// 	Where L and R refer to left and right lines, y = ax + b, and r is radius on corners
// 	rc_arry[] is used to dummy up an argument list, rc_arry[] = {aL, bL, aR, bR,  r}
// 								  = { 0,  1,  2,  3,  4}

Function radius_corner
  angleL = Atan2(rc_arry[0], 1.0); // Printf("rc_arry[0]=%f, angleL=%f", rc_arry[0], angleL);
  angleR = Atan2(rc_arry[2], 1.0);
  If (angleL == angleR)
    Error("Two lines may not be parallel for radiusing");
  EndIf
  sign = (angleL > angleR ? 1.0 : -1.0);
  x_center = ((rc_arry[1] - rc_arry[3]) + sign*rc_arry[4]*(1/Cos(angleR) - 1/Cos(angleL)))
	      /(rc_arry[2] - rc_arry[0]);
  y_center = rc_arry[0] * x_center + rc_arry[1] - sign*rc_arry[4]/Cos(angleL);
  PC = newp;  Point(PC) = {x_center, y_center, 0, mesh_sz};
  
  PL = newp; Point(PL) = {x_center - sign*rc_arry[4]*Sin(angleL), y_center + sign*rc_arry[4]*Cos(angleL), 0, mesh_sz};
  PR = newp; Point(PR) = {x_center - sign*rc_arry[4]*Sin(angleR), y_center + sign*rc_arry[4]*Cos(angleR), 0, mesh_sz};
  radii_one = newl; Circle(radii_one) = {PL, PC, PR};
  x_center = (rc_arry[1] - rc_arry[3])
	      /(rc_arry[2] - rc_arry[0]);
  y_center = rc_arry[0] * x_center + rc_arry[1];
  PInt = newp; Point(PInt) = {x_center, y_center, 0, mesh_sz};
Return

// Function radius_int(PIntL, PInt, PIntR, r)
// 	Where PtL, PtC, PtR, r refer to Points left, center and right, and r is radius
// 	rint_arry[] is used to dummy up an argument list, rint_arry[] = (PIntL, PInt, PIntR, r)
// 								      = {    0,    1,     2,  3}
Function radius_int
  PIntL =  rint_arry[0]; PInt =  rint_arry[1]; PIntR =  rint_arry[2];
  xlf[] = Point{PIntL}; xint[] = Point{PInt}; xrt[] = Point{PIntR};

  If (((xrt[0] - xint[0]) != 0) && ((xint[0] - xlf[0]) != 0))  // check for vertical line
    If (rint_arry[3] > 0.0)	// radius intersection
      rc_arry[] = {(xint[1] - xlf[1])/(xint[0] - xlf[0]),
		    xint[1] - ((xint[1] - xlf[1])/(xint[0] - xlf[0]))*xint[0],
		    (xrt[1] - xint[1])/(xrt[0] - xint[0]),
		    xint[1] - ((xrt[1] - xint[1])/(xrt[0] - xint[0]))*xint[0],
		    rint_arry[3]};
      Call radius_corner;
    EndIf  
    If (rint_arry[3] == 0.0)	// radius is zero, set all points to PInt so that the lines will intersect
      PL = PR = PInt
    EndIf
  EndIf
  
  If ((xrt[0] - xint[0]) == 0)  // check for vertical line
    If (rint_arry[3] > 0.0)	// radius intersection
      x_center = xrt[0] - rint_arry[3];
      A  = (xint[1] - xlf[1])/(xint[0] - xlf[0]);
      B  = xint[1] - A * xint[0] + (rint_arry[3] * Sqrt(A^2 + 1));
      y_center = A * x_center + B;
      PC = newp; Point(PC) = {x_center, y_center, 0, mesh_sz};
      PL = newp; Point(PL) = {x_center + rint_arry[3], y_center, 0, mesh_sz};
      angleL = Atan(A); PR = newp; Point(PR) = {x_center + rint_arry[3]*Sin(angleL), y_center - rint_arry[3]*Cos(angleL), 0, mesh_sz};
      radii_one = newl; Circle(radii_one) = {PL, PC, PR};
    EndIf  
    If (rint_arry[3] == 0.0)	// radius is zero, set all points to PInt so that the lines will intersect
      PL = PR = PInt
    EndIf
  EndIf
Return

// Function pt2line(PL1, PL2, PT), dist
// 	Where PL1, PL2 refer to line points left, right; PT is the reference point and dist, distance to the right
// 	pt2line_arry[] is used to dummy up an argument list, pt2line_arry[] = (PL1, PL2, PT), dist
// 								      = {    0,    1,     2}
Function pt2line
  PL1 =  pt2line_arry[0]; PL2 =  pt2line_arry[1]; PT =  pt2line_arry[2];
  xlf[] = Point{PL1}; xrt[] = Point{PL2}; xint[] = Point{PT};
  a = (xrt[1] - xlf[1])/(xrt[0] - xlf[0]);
  angleL = Atan2((xrt[1] - xlf[1]), (xrt[0] - xlf[0]));
  dist = ((xint[1]  - a*xint[0]) - (xlf[1]  - a*xlf[0])) * Cos(angleL);  Printf("dist=%f", dist);
Return

// Function dbl_radii(PT1, HT, AngleR, R1, R2)
// 								      = {    0,    1,     2}
Function dbl_radii
  PT1 =  dbl_radii_arry[0]; HT =  dbl_radii_arry[1]; AngleR =  dbl_radii_arry[2]; R1 =  dbl_radii_arry[3]; R2 =  dbl_radii_arry[4];
  Angle2 = AngleR / (R2/R1 + 1.0); Angle1 = AngleR - Angle2;
  cp[] = Point{PT1};
  delta_x = - ((R2 - R1) * Sin(Angle2) + R1 * Sin(AngleR));
  delta_y = R2 - (R2 - R1) * Cos(Angle2) - R1 * Cos(AngleR);
  B = cp[1] + Tan(AngleR) * cp[0];
  Y = HT - delta_y; X = (B - Y)/Tan(AngleR); PtR = newp;  Point(newp) = {X, Y, 0, mesh_sz};
  Y -=  R1 * Cos(AngleR); X -=  R1 * Sin(AngleR); PtC = newp;  Point(newp) = {X, Y, 0, mesh_sz};
  Y +=  R1 * Cos(Angle2); X +=  R1 * Sin(Angle2); PtL = newp;  Point(newp) = {X, Y, 0, mesh_sz};
  radii_one = newl; Circle(radii_one) = {PtL, PtC, PtR}; arc_pts[] = {PtR, PtC, PtL}; Call arc_dxf;
  PtR = PtL;
  Y -=  R2 * Cos(Angle2); X -=  R2 * Sin(Angle2); PtC = newp;  Point(newp) = {X, Y, 0, mesh_sz};
  Y  =  HT; PtL = newp;  Point(newp) = {X, Y, 0, mesh_sz};
  radii_two = newl; Circle(radii_two) = {PtL, PtC, PtR}; arc_pts[] = {PtR, PtC, PtL}; Call arc_dxf;
Return

// Function dxf_init
Function dxf_init
  Printf(Str("0", "SECTION", "2", "ENTITIES")) > dxf_file;
Return

// Function line_dxf(line_dxf_num)
Function line_dxf
  func_pt[] = Point{cL[0]};
  Printf(Str("  0", "LINE", "  8", "Gun_Geom", "10")) >> dxf_file; // layer "Gun_Geom"
  Printf("%f", func_pt[0]/m_per_mm) >> dxf_file;  // x0
  Printf(" 20") >> dxf_file;
  Printf("%f", func_pt[1]/m_per_mm) >> dxf_file;  // y0
  Printf(" 11") >> dxf_file;
  func_pt[] = Point{cL[1]};
  Printf("%f", func_pt[0]/m_per_mm) >> dxf_file;  // x1
  Printf(" 21") >> dxf_file;
  Printf("%f", func_pt[1]/m_per_mm) >> dxf_file;  // y1
Return

// Function line_dxf(arc_dxf_num);  arc_pts[] = {pt_start, pt_center, pt_stop};
Function arc_dxf
  If (arc_pts[0] != arc_pts[2])	//  draw if the points are different, if the same, there is no radius
    ctr_pt[] = Point{arc_pts[1]};
    start_pt[] = Point{arc_pts[0]};
    stop_pt[] = Point{arc_pts[2]};
    Printf(Str("  0", "ARC", "  8", "Gun_Geom", " 10")) >> dxf_file;
    Printf("%f", ctr_pt[0]/m_per_mm) >> dxf_file; // xC
    Printf(" 20") >> dxf_file;
    Printf("%f", ctr_pt[1]/m_per_mm) >> dxf_file; // yC
    Printf(" 40") >> dxf_file;
    Printf("%f", Sqrt((ctr_pt[0]-start_pt[0])^2 + (ctr_pt[1]-start_pt[1])^2)/m_per_mm) >> dxf_file; // radius
    Printf(" 50") >> dxf_file;
    Printf("%f", (180/Pi) * Atan2(start_pt[1]-ctr_pt[1], start_pt[0]-ctr_pt[0])) >> dxf_file; // angle_start (degrees)
    Printf(" 51") >> dxf_file;
    Printf("%f", (180/Pi) * Atan2(stop_pt[1]-ctr_pt[1], stop_pt[0]-ctr_pt[0])) >> dxf_file; // angle_stop (degrees)
  EndIf
Return

// Function dxf_complete
Function dxf_complete
  Printf(Str("0", "ENDSEC", "0", "EOF")) >> dxf_file;
Return




----- Original Message -----
From: "Christophe Geuzaine" <cgeuzaine at ulg.ac.be>
To: "Danny Holstein" <dgholstein at embarqmail.com>
Cc: gmsh at geuz.org
Sent: Thursday, March 5, 2015 12:43:25 PM
Subject: Re: [Gmsh] If () Endif issues


> On 24 Feb 2015, at 15:03, Danny Holstein <dgholstein at embarqmail.com> wrote:
> 
> Thanks so much, that was simple!
> 
> On a related question (related to my geometry, that is), is there a way to construct a line loop using an array of lines?  When parametrizing, I will not have the same number of line features depending on whether I radius a corner or not (as well as other conditionals).  It would be easy to add line elements to an array and then form the line loop with those, I don't see how to do it otherwise.
> 
> Are there some GMSH array examples to look at?  Arrays of points, of lines?
> 

Sure, just construct an array with the IDs of the points/lines you want ; see e.g. tutorial/t5.geo where a surface loop is constructed this way.

There are many useful operators on lists, e.g. += to append or -= to remove. The "Boundary" and "CombinedBoundary" operators are also often useful to automate boundary generation.

Christophe


> Regards,
> Dan
> 
> ----- Original Message -----
> From: "Christophe Geuzaine" <cgeuzaine at ulg.ac.be>
> To: "Danny Holstein" <dgholstein at embarqmail.com>
> Cc: gmsh at geuz.org
> Sent: Tuesday, February 24, 2015 3:17:42 AM
> Subject: Re: [Gmsh] If () Endif issues
> 
> 
>> On 24 Feb 2015, at 04:21, Danny Holstein <dgholstein at embarqmail.com> wrote:
>> 
>> All,
>> 
>> The attached crashes GMSH versions 2.8.6 and 2.8.5 on Linux x86_64 when the logical resolves to "false".
>> 
>> Also, when it resolves to "true", it doesn't read the following script line, so I put in a semicolon, which causes the scripting language to throw an "error".
>> 
> 
> Hi Danny - Change "Endif" into "EndIf" on line 16 of functions.dat. (We will try to fix the crash, which is due to an unclean file close.)
> 
>> Any help would be appreciated.
>> 
>> Regards,
>> Dan
>> <functions.dat><keri.dat><keri.geo>_______________________________________________
>> gmsh mailing list
>> gmsh at geuz.org
>> http://www.geuz.org/mailman/listinfo/gmsh
> 
> -- 
> Prof. Christophe Geuzaine
> University of Liege, Electrical Engineering and Computer Science 
> http://www.montefiore.ulg.ac.be/~geuzaine
> 
> 
> 
> 
> _______________________________________________
> gmsh mailing list
> gmsh at geuz.org
> http://www.geuz.org/mailman/listinfo/gmsh

-- 
Prof. Christophe Geuzaine
University of Liege, Electrical Engineering and Computer Science 
http://www.montefiore.ulg.ac.be/~geuzaine