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!"); }
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; }
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; }
/** * @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; }
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); }
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; }
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(); }
//======================================================================= // 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; }