+ BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction());
+ if(!aProjector.IsDone())
+ return false;
+ TopoDS_Shape aPrjProfile = aProjector.Shape();
+ if(aPrjProfile.IsNull())
+ return false;
+ TopoDS_Vertex aV1, aV2;
+ if(aPrjProfile.ShapeType() == TopAbs_EDGE)
+ TopExp::Vertices(TopoDS::Edge(aPrjProfile), aV1, aV2);
+ else if(aPrjProfile.ShapeType() == TopAbs_WIRE)
+ TopExp::Vertices(TopoDS::Wire(aPrjProfile), aV1, aV2);
+ else if(aPrjProfile.ShapeType() == TopAbs_COMPOUND){
+ TopExp_Explorer anExp(aPrjProfile, TopAbs_WIRE);
+ if(anExp.More()) {
+ TopExp::Vertices(TopoDS::Wire(anExp.Current()), aV1, aV2);
+ } else {
+ anExp.Init(aPrjProfile, TopAbs_EDGE);
+ if(anExp.More()) {
+ TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV1, aV2);
+ }
+ }
+ }
+ if(aV1.IsNull() || aV2.IsNull())
+ return false;
+ gp_Pnt aPnt1 = BRep_Tool::Pnt(aV1);
+ gp_Pnt aPnt2 = BRep_Tool::Pnt(aV2);
+ aPnt1.SetZ(0.0);
+ aPnt2.SetZ(0.0);
+ BRepBuilderAPI_MakeEdge aMk(aPnt1, aPnt2);
+ if(!aMk.IsDone())
+ return false;
+ const TopoDS_Edge& anEdg2 = aMk.Edge();//Section edge
+ Standard_Integer aNum(0);
+
+ TopExp_Explorer anExplo(aHydraulicWire, TopAbs_EDGE);
+ for(;anExplo.More();anExplo.Next()) aNum++;
+ // check for self-intersection
+ const Standard_Real SquareTolerance = Precision::Confusion()*Precision::Confusion();
+ Standard_Boolean hasInt(false);
+ Standard_Real aSqDist(DBL_MAX);
+ Standard_Integer anIndx(0);
+ BRepExtrema_ExtCC aCC;
+ aCC.Initialize(anEdg2);
+ theOutPar = 0.0;
+ anExplo.Init(aHydraulicWire, TopAbs_EDGE);
+ for(Standard_Integer j=1;anExplo.More();anExplo.Next(),j++) {
+ const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current());
+ if(anEdg1.IsNull())
+ continue;
+ Standard_Boolean hasSol(false);
+ aCC.Perform(anEdg1);
+ if(aCC.IsDone()) {
+ // find minimal dist
+ for(Standard_Integer i=1; i<= aCC.NbExt();i++)
+ if(aCC.SquareDistance(i) < aSqDist) {
+ aSqDist = aCC.SquareDistance(i);
+ anIndx = i;
+ hasSol = true;
+ }
+ }
+ if(hasSol) {
+ if(aSqDist <= SquareTolerance) { // hasInt
+ const gp_Pnt& aPnt = aCC.PointOnE1(anIndx);
+ if(aNum > 1) {
+ TopExp::Vertices(anEdg1, aV1, aV2, Standard_True);
+ theOutPar += BRep_Tool::Pnt(aV1).Distance(aPnt);
+ } else {
+ Standard_Real aPar = aCC.ParameterOnE1(anIndx);
+ theOutPar = aPar;
+ }
+ hasInt = true;
+ break;
+ } else {
+ // no ints-n
+ if(aNum > 1) {
+ TopExp::Vertices(anEdg1, aV1, aV2);
+ theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
+ }
+ }
+ } else if(aNum > 1) {
+ TopExp::Vertices(anEdg1, aV1, aV2);
+ theOutPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2));
+ }
+ }
+ if(hasInt)
+ return true;
+ return false;