Exemplo n.º 1
0
EtaXsi computeRibSparIntersectionEtaXsi(const CTiglWingStructureReference& wsr, const CCPACSWingRibsDefinition& rib, int ribIndex, const CCPACSWingSparSegment& spar)
{
    // determine rib eta/xsi values
    gp_Pnt ribStartPoint, ribEndPoint;
    rib.GetRibMidplanePoints(ribIndex, ribStartPoint, ribEndPoint);

    EtaXsi ribStart, ribEnd;
    wsr.GetMidplaneEtaXsi(ribStartPoint, ribStart.eta, ribStart.xsi);
    wsr.GetMidplaneEtaXsi(ribEndPoint, ribEnd.eta, ribEnd.xsi);

    // determine number of spar positions
    int numSparPositions = spar.GetSparPositionUIDCount();

    const double precision = 1E-8;
    const double zeroMin = 0 - precision;
    EtaXsi sparInner, sparOuter;
    spar.GetEtaXsi(1, sparInner.eta, sparInner.xsi);
    for (int i = 2; i <= numSparPositions; ++i) {
        // check if requested eta lies in current spar line segment
        spar.GetEtaXsi(i, sparOuter.eta, sparOuter.xsi);

        // 2d line intersection, taken from http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
        gp_Pnt2d p(ribStart.eta, ribStart.xsi);
        gp_Vec2d r(p, gp_Pnt2d(ribEnd.eta, ribEnd.xsi));

        gp_Pnt2d q(sparInner.eta, sparInner.xsi);
        gp_Vec2d s(q, gp_Pnt2d(sparOuter.eta, sparOuter.xsi));

        double rxs = r.Crossed(s);
        // ignore parallel or colinear lines
        if (fabs(rxs) > precision) {
            double t = gp_Vec2d(p, q).Crossed(s) / rxs;
            double u = gp_Vec2d(p, q).Crossed(r) / rxs;
            if (t >= zeroMin && t <= (1 + precision) && u >= zeroMin && u <= (1 + precision)) {
                return EtaXsi(p.X() + t * r.X(), p.Y() + t * r.Y());
            }
        }

        sparInner = sparOuter;
    }

    throw CTiglError("Error in computeRibSparIntersectionEtaXsi: intersection of rib and spar not found!");
}
Exemplo n.º 2
0
gp_Pnt GetCentralFacePoint(const TopoDS_Face& face)
{
    // compute point on face
    Standard_Real umin, umax, vmin, vmax;

    gp_Pnt p;

    Handle(Geom_Surface) surface = BRep_Tool::Surface(face);
    BRepTools::UVBounds(face, umin, umax, vmin, vmax);
    Standard_Real umean = 0.5*(umin+umax);
    Standard_Real vmean = 0.5*(vmin+vmax);


    // compute intersection of u-iso line with face boundaries
    Handle(Geom2d_Curve) uiso = new Geom2d_Line(
                gp_Pnt2d(umean,0.),
                gp_Dir2d(0., 1.)
                );

    TopExp_Explorer exp (face,TopAbs_EDGE);
    std::list<double> intersections;
    for (; exp.More(); exp.Next()) {
        TopoDS_Edge edge = TopoDS::Edge(exp.Current());
        Standard_Real first, last;

        // Get geomteric curve from edge
        Handle(Geom2d_Curve) hcurve = BRep_Tool::CurveOnSurface(edge, face, first, last);
        hcurve = new Geom2d_TrimmedCurve(hcurve, first, last);

        Geom2dAPI_InterCurveCurve intersector(uiso, hcurve);
        for (int ipoint = 0; ipoint < intersector.NbPoints(); ++ipoint) {
            gp_Pnt2d p = intersector.Point(ipoint+1);
            intersections.push_back(p.Y());
        }
    }

    // remove duplicate solutions defined by tolerance
    double tolerance = 1e-5;
    intersections.sort();
    intersections.unique(IsSame((vmax-vmin)*tolerance));

    // normally we should have at least two intersections
    // also the number of sections should be even - else something is really strange
    //assert(intersections.size() % 2 == 0);
    if (intersections.size() >= 2) {
        std::list<double>::iterator it = intersections.begin();
        double int1 = *it++;
        double int2 = *it;
        vmean = (int1 + int2)/2.;
    }

    surface->D0(umean, vmean, p);

    return p;
}
Exemplo n.º 3
0
bool IfcGeom::convert(const Ifc2x3::IfcAxis2Placement2D::ptr l, gp_Trsf2d& trsf) {
	IN_CACHE(IfcAxis2Placement2D,l,gp_Trsf2d,trsf)
	gp_Pnt P; gp_Dir V (1,0,0);
	IfcGeom::convert(l->Location(),P);
	if ( l->hasRefDirection() )
		IfcGeom::convert(l->RefDirection(),V);

	gp_Ax2d axis(gp_Pnt2d(P.X(),P.Y()),gp_Dir2d(V.X(),V.Y()));
	trsf.SetTransformation(axis,gp_Ax2d());
	CACHE(IfcAxis2Placement2D,l,trsf)
	return true;
}
Exemplo n.º 4
0
 /**
  * @brief getFaceTrimmingEdge Creates an edge in parameter space to trim a face
  * @return 
  */
 TopoDS_Edge getFaceTrimmingEdge(const TopoDS_Face& face, double ustart, double vstart, double uend, double vend)
 {
     Handle_Geom_Surface surf = BRep_Tool::Surface(face);
     Handle(Geom2d_TrimmedCurve) line = GCE2d_MakeSegment(gp_Pnt2d(ustart,vstart), gp_Pnt2d(uend,vend));
 
     BRepBuilderAPI_MakeEdge edgemaker(line, surf);
     TopoDS_Edge edge =  edgemaker.Edge();
     
     // this here is really important
     BRepLib::BuildCurves3d(edge);
     return edge;
 }
Exemplo n.º 5
0
bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator2D::ptr l, gp_Trsf2d& trsf) {
	IN_CACHE(IfcCartesianTransformationOperator2D,l,gp_Trsf2d,trsf)
	gp_Pnt origin;
	IfcGeom::convert(l->LocalOrigin(),origin);
	gp_Dir axis1 (1.,0.,0.);
	if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
	const gp_Ax2d ax2d (gp_Pnt2d(origin.X(),origin.Y()),gp_Dir2d(axis1.X(),axis1.Y()));
	trsf.SetTransformation(ax2d);
	trsf.Invert();
	if ( l->hasScale() ) trsf.SetScaleFactor(l->Scale());
	CACHE(IfcCartesianTransformationOperator2D,l,trsf)
	return true;
}
static Handle(Geom2d_Curve) mk2dBezierCurve(const Standard_Integer nPoles,
        const Standard_Real theCoords[][2],
        const Standard_Real aScale = 1,
        const gp_XY& aShift = gp_XY(0,0))
{
    TColgp_Array1OfPnt2d aPoles (1, nPoles);
    for (Standard_Integer i=0; i < nPoles; i++)
    {
        gp_XY aP (theCoords[i][0], theCoords[i][1]);
        aPoles(i+1) = gp_Pnt2d (aP * aScale + aShift);
    }
    return new Geom2d_BezierCurve (aPoles);
}
Exemplo n.º 7
0
bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator2DnonUniform::ptr l, gp_GTrsf2d& gtrsf) {
	IN_CACHE(IfcCartesianTransformationOperator2DnonUniform,l,gp_GTrsf2d,gtrsf)
	gp_Trsf2d trsf;
	gp_Pnt origin;
	IfcGeom::convert(l->LocalOrigin(),origin);
	gp_Dir axis1 (1.,0.,0.);
	if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
	const gp_Ax2d ax2d (gp_Pnt2d(origin.X(),origin.Y()),gp_Dir2d(axis1.X(),axis1.Y()));
	trsf.SetTransformation(ax2d);
	trsf.Invert();
	const double scale1 = l->hasScale() ? l->Scale() : 1.0f;
	const double scale2 = l->hasScale2() ? l->Scale2() : scale1;
	gtrsf = gp_GTrsf2d();
	gtrsf.SetValue(1,1,scale1);
	gtrsf.SetValue(2,2,scale2);
	gtrsf.Multiply(trsf);
	CACHE(IfcCartesianTransformationOperator2DnonUniform,l,gtrsf)
	return true;
}
Exemplo n.º 8
0
gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
                                    const SMDS_MeshNode* n,
                                    const SMDS_MeshNode* n2) const
{
  gp_Pnt2d uv( 1e100, 1e100 );
  const SMDS_PositionPtr Pos = n->GetPosition();
  if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE)
  {
    // node has position on face
    const SMDS_FacePosition* fpos =
      static_cast<const SMDS_FacePosition*>(n->GetPosition().get());
    uv = gp_Pnt2d(fpos->GetUParameter(),fpos->GetVParameter());
  }
  else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE)
  {
    // node has position on edge => it is needed to find
    // corresponding edge from face, get pcurve for this
    // edge and recieve value from this pcurve
    const SMDS_EdgePosition* epos =
      static_cast<const SMDS_EdgePosition*>(n->GetPosition().get());
    SMESHDS_Mesh* meshDS = GetMeshDS();
    int edgeID = Pos->GetShapeId();
    TopoDS_Edge E = TopoDS::Edge(meshDS->IndexToShape(edgeID));
    double f, l;
    Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
    uv = C2d->Value( epos->GetUParameter() );
    // for a node on a seam edge select one of UVs on 2 pcurves
    if ( n2 && IsSeamShape( edgeID ) )
      uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
  }
  else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX)
  {
    if ( int vertexID = n->GetPosition()->GetShapeId() ) {
      bool ok = true;
      const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID));
      try {
        uv = BRep_Tool::Parameters( V, F );
      }
      catch (Standard_Failure& exc) {
        ok = false;
      }
      if ( !ok ) {
        for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !ok && vert.More(); vert.Next() )
          ok = ( V == vert.Current() );
        if ( !ok ) {
#ifdef _DEBUG_
          MESSAGE ( "SMESH_MesherHelper::GetNodeUV(); Vertex " << vertexID
               << " not in face " << GetMeshDS()->ShapeToIndex( F ) );
#endif
          // get UV of a vertex closest to the node
          double dist = 1e100;
          gp_Pnt pn ( n->X(),n->Y(),n->Z() );
          for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !ok && vert.More(); vert.Next() ) {
            TopoDS_Vertex curV = TopoDS::Vertex( vert.Current() );
            gp_Pnt p = BRep_Tool::Pnt( curV );
            double curDist = p.SquareDistance( pn );
            if ( curDist < dist ) {
              dist = curDist;
              uv = BRep_Tool::Parameters( curV, F );
              if ( dist < DBL_MIN ) break;
            }
          }
        }
        else {
          TopTools_ListIteratorOfListOfShape it( myMesh->GetAncestors( V ));
          for ( ; it.More(); it.Next() ) {
            if ( it.Value().ShapeType() == TopAbs_EDGE ) {
              const TopoDS_Edge & edge = TopoDS::Edge( it.Value() );
              double f,l;
              Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edge, F, f, l);
              if ( !C2d.IsNull() ) {
                double u = ( V == TopExp::FirstVertex( edge ) ) ?  f : l;
                uv = C2d->Value( u );
                break;
              }
            }
          }
        }
      }
      if ( n2 && IsSeamShape( vertexID ) )
        uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
    }
  }
  return uv.XY();
}
Exemplo n.º 9
0
//=======================================================================
// profile
// command to build a profile
//=======================================================================
Sketcher_Profile::Sketcher_Profile(const char* aCmd)
{
  enum {line, circle, point, none} move;

  Standard_Integer i = 1;
  Standard_Real x0, y0, x, y, dx, dy;
  x0 = y0 = x = y = dy = 0;
  dx = 1;

  Standard_Boolean first, stayfirst, face, close;
  first = Standard_True;
  stayfirst = face = close = Standard_False;

  Standard_Integer reversed = 0;
  Standard_Integer control_Tolerance = 0;

  TopoDS_Shape S;
  TopoDS_Vertex MP;
  BRepBuilderAPI_MakeWire MW;
  gp_Ax3 DummyHP(gp::XOY());
  gp_Pln P(DummyHP);
  TopLoc_Location TheLocation;
  Handle(Geom_Surface) Surface;

  myOK = Standard_False;
  myError = 0;

  //TCollection_AsciiString aCommand(CORBA::string_dup(aCmd));
  TCollection_AsciiString aCommand ((char*)aCmd);
  TCollection_AsciiString aToken = aCommand.Token(":", 1);
  int n = 0;
  // porting to WNT
  TColStd_Array1OfAsciiString aTab (0, aCommand.Length() - 1);
  if ( aCommand.Length() )
  {
    while(aToken.Length() != 0) {
      if(aCommand.Token(":", n + 1).Length() > 0)
        aTab(n) = aCommand.Token(":", n + 1);
      aToken = aCommand.Token(":", ++n);
    }
    n = n - 1;
  }
  if ( aTab.Length() && aTab(0).Length() )
    while(i < n) {
      Standard_Real length = 0, radius = 0, angle = 0;
      move = point;

      int n1 = 0;
      TColStd_Array1OfAsciiString a (0, aTab(0).Length());
      aToken = aTab(i).Token(" ", 1);
      while (aToken.Length() != 0) {
        if (aTab(i).Token(" ", n1 + 1).Length() > 0)
          a(n1) = aTab(i).Token(" ", n1 + 1);
        aToken = aTab(i).Token(" ", ++n1);
      }
      n1 = n1 - 1;

      switch(a(0).Value(1))
      {
      case 'F':
        {
          if (n1 != 3) goto badargs;
          if (!first) {
            MESSAGE("profile : The F instruction must precede all moves");
            return;
          }
          x0 = x = a(1).RealValue();
          y0 = y = a(2).RealValue();
          stayfirst = Standard_True;
          break;
        }
      case 'O':
        {
          if (n1 != 4) goto badargs;
          P.SetLocation(gp_Pnt(a(1).RealValue(), a(2).RealValue(), a(3).RealValue()));
          stayfirst = Standard_True;
          break;
        }
      case 'P':
        {
          if (n1 != 7) goto badargs;
          gp_Vec vn(a(1).RealValue(), a(2).RealValue(), a(3).RealValue());
          gp_Vec vx(a(4).RealValue(), a(5).RealValue(), a(6).RealValue());
          if (vn.Magnitude() <= Precision::Confusion() || vx.Magnitude() <= Precision::Confusion()) {
            MESSAGE("profile : null direction");
            return;
          }
          gp_Ax2 ax(P.Location(), vn, vx);
          P.SetPosition(ax);
          stayfirst = Standard_True;
          break;
        }
      case 'X':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (a(0) == "XX")
            length -= x;
          dx = 1; dy = 0;
          move = line;
          break;
        }
      case 'Y':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (a(0) == "YY")
            length -= y;
          dx = 0; dy = 1;
          move = line;
          break;
        }
      case 'L':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (Abs(length) > Precision::Confusion())
            move = line;
          else
            move = none;
          break;
        }
      case 'T':
        {
          if (n1 != 3) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          if (a(0) == "TT") {
            vx -= x;
            vy -= y;
          }
          length = Sqrt(vx * vx + vy * vy);
          if (length > Precision::Confusion()) {
            move = line;
            dx = vx / length;
            dy = vy / length;
          }
          else
            move = none;
          break;
        }
      case 'R':
        {
          if (n1 != 2) goto badargs;
          angle = a(1).RealValue() * PI180;
          if (a(0) == "RR") {
            dx = Cos(angle);
            dy = Sin(angle);
          }
          else {
            Standard_Real c = Cos(angle);
            Standard_Real s = Sin(angle);
            Standard_Real t = c * dx - s * dy;
            dy = s * dx + c * dy;
            dx = t;
          }
          break;
        }
      case 'D':
        {
          if (n1 != 3) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          length = Sqrt(vx * vx + vy * vy);
          if (length > Precision::Confusion()) {
            dx = vx / length;
            dy = vy / length;
          }
          else
            move = none;
          break;
        }
      case 'C':
        {
          if (n1 != 3) goto badargs;
          radius = a(1).RealValue();
          if (Abs(radius) > Precision::Confusion()) {
            angle = a(2).RealValue() * PI180;
            move = circle;
          }
          else
            move = none;
          break;
        }
      case 'A':                                // TAngential arc by end point   
        { 
          if (n1 != 3) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue(); 
          if (a(0) == "AA") {
            vx -= x;
            vy -= y;
          }
          Standard_Real det = dx * vy - dy * vx;
          if ( Abs(det) > Precision::Confusion()) {
            Standard_Real c = (dx * vx + dy * vy)                                            
                              / Sqrt((dx * dx + dy * dy) * (vx * vx + vy * vy));                 // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi]
            radius = (vx * vx + vy * vy)* Sqrt(dx * dx + dy * dy)                                // radius = distance between start and end point / 2 * sin(alpha)  
                     / (2.0 * det);	                                                             // radius is > 0 or < 0
            if (Abs(radius) > Precision::Confusion()) {
              angle = 2.0 * acos(c); 	                                                         // angle in [0,2Pi]  
              move = circle;
            }
            else
              move = none;
            break;
          } 
          else
            move = none;
          break;
        } 
      case 'U':                                // Arc by end point and radiUs
        { 
          if (n1 != 5) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          radius  = a(3).RealValue();
          reversed = a(4).IntegerValue();
          if (a(0) == "UU") {                 // Absolute
            vx -= x;
            vy -= y;
          }
          Standard_Real length = Sqrt(vx * vx + vy * vy);
          if ( (4.0 - (vx * vx + vy * vy) / (radius * radius) >= 0.0 ) && (length > Precision::Confusion()) ) {
            Standard_Real c = 0.5 * Sqrt(4.0 - (vx * vx + vy * vy) / (radius * radius));        // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2]
            angle = 2.0 * acos(c); 	                                                            // angle in [0,Pi]
            if ( reversed == 2 )
              angle = angle - 2 * PI; 
            dx =    0.5 * (  vy * 1.0/radius 
                           + vx * Sqrt(4.0  / (vx * vx + vy * vy) - 1.0 / (radius * radius)));    
            dy = -  0.5 * (  vx * 1.0/radius 
                           - vy * Sqrt(4.0  / (vx * vx + vy * vy) - 1.0 / (radius * radius)));    
            move = circle;
          }
          else{
            move = none;
          }
          break;
        }	 
      case 'E':                                // Arc by end point and cEnter
        { 
          if (n1 != 7) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          Standard_Real vxc  = a(3).RealValue();
          Standard_Real vyc  = a(4).RealValue();
          reversed = a(5).IntegerValue();
          control_Tolerance = a(6).IntegerValue();

          if (a(0) == "EE") {                 // Absolute
            vx -= x;
            vy -= y;
            vxc -= x;
            vyc -= y; 
          }
          radius = Sqrt( vxc * vxc + vyc * vyc );
          Standard_Real det = vx * vyc - vy * vxc;
          Standard_Real length = Sqrt(vx * vx + vy * vy);
          Standard_Real length2 = Sqrt((vx-vxc) * (vx-vxc) + (vy-vyc) * (vy-vyc));
          Standard_Real length3 = Sqrt(vxc * vxc + vyc * vyc);
          Standard_Real error = Abs(length2 - radius);
          myError = error;
          if ( error > Precision::Confusion() ){
            MESSAGE("Warning : The specified end point is not on the Arc, distance = "<<error);
          }
          if ( error > Precision::Confusion() && control_Tolerance == 1)                      // Don't create the arc if the end point 
            move = none;                                                                      // is too far from it
          else if ( (length > Precision::Confusion()) && 
                    (length2 > Precision::Confusion()) && 
                    (length3 > Precision::Confusion()) ) {
            Standard_Real c = ( radius * radius - (vx * vxc + vy * vyc) ) 
                            / ( radius * Sqrt((vx-vxc) * (vx-vxc) + (vy-vyc) * (vy-vyc)) ) ;  // Cosine of arc angle 
            angle = acos(c);                                                                  // angle in [0,Pi] 
            if ( reversed == 2 )
              angle = angle - 2 * PI;
            if (det < 0)
              angle = -angle; 
            dx =  vyc / radius;
            dy = -vxc / radius; 
            move = circle;
          }
          else {
            move = none;
          }
          break;
        }	
      case 'I':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (a(0) == "IX") {
            if (Abs(dx) < Precision::Confusion()) {
              MESSAGE("profile : cannot intersect, arg "<<i-1);
              return;
            }
            length = (length - x) / dx;
          }
          else if (a(0) == "IY") {
            if (Abs(dy) < Precision::Confusion()) {
              MESSAGE("profile : cannot intersect, arg "<<i-1);
              return;
            }
            length = (length - y) / dy;
          }
          if (Abs(length) > Precision::Confusion())
            move = line;
          else
            move = none;
          break;
        }
      case 'W':
        {
          if (a(0) == "WW")
            close = Standard_True;
          else if(a(0) == "WF") {
            close = Standard_True;
            face = Standard_True;
          }
          i = n - 1;
          break;
        }
      default:
        {
          MESSAGE("profile : unknown code " << a(i));
          return;
        }
    }

again :
    switch (move)
    {
    case line :
      {
        if (length < 0) {
          length = -length;
          dx = -dx;
          dy = -dy;
        }
        Handle(Geom2d_Line) l = new Geom2d_Line(gp_Pnt2d(x,y),gp_Dir2d(dx,dy));
        BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(l,P),0,length);
        if (!ME.IsDone())
          return;
        MW.Add(ME);
        x += length*dx;
        y += length*dy;
        break;
      }
    case circle :
      {
        Standard_Boolean sense = Standard_True;
        if (radius < 0) {
          radius = -radius;
          sense = !sense;
          dx = -dx;
          dy = -dy;
        }
        gp_Ax2d ax(gp_Pnt2d(x-radius*dy,y+radius*dx),gp_Dir2d(dy,-dx));
        if (angle < 0) {
          angle = -angle;
          sense = !sense;
        }
        Handle(Geom2d_Circle) c = new Geom2d_Circle(ax,radius,sense);
        BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(c,P),0,angle);
        if (!ME.IsDone())
          return;
        MW.Add(ME);
        gp_Pnt2d p;
        gp_Vec2d v;
        c->D1(angle,p,v);
        x = p.X();
        y = p.Y();
        dx = v.X() / radius;
        dy = v.Y() / radius;
        break;
      }
    case point:
      {
        MP = BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, 0.0));
        break;
      }
    case none:
      {
        i = n - 1;
        break;
      }
    }

    // update first
    first = stayfirst;
    stayfirst = Standard_False;

    if(!(dx == 0 && dy == 0))
      myLastDir.SetCoord(dx, dy, 0.0);
    else
      return;
    myLastPoint.SetX(x);
    myLastPoint.SetY(y);

    // next segment....
    i++;
    if ((i == n) && close) {
      // the closing segment
      dx = x0 - x;
      dy = y0 - y;
      length = Sqrt(dx * dx + dy * dy);
      move = line;
      if (length > Precision::Confusion()) {
        dx = dx / length;
        dy = dy / length;
        goto again;
      }
    }
  }

  // get the result, face or wire
  if (move == none) {
    return;
  } else if (move == point) {
    S = MP;
  } else if (face) {
    if (!MW.IsDone()) {
      return;
    }
    BRepBuilderAPI_MakeFace MF (P, MW.Wire());
    if (!MF.IsDone()) {
      return;
    }
    S = MF;
  } else {
    if (!MW.IsDone()) {
      return;
    }
    S = MW;
  }

  if(!TheLocation.IsIdentity())
    S.Move(TheLocation);

  myShape = S;
  myOK = true;
  return;

  badargs :
    MESSAGE("profile : bad number of arguments");
    return;
}