// File: IntPoly_PlaneSection.cxx // Created: Mon Jul 17 10:46:23 1995 // Author: Stagiaire Alain JOURDAIN // #include #include #include #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : IntPoly_PlaneSection //purpose : //======================================================================= IntPoly_PlaneSection::IntPoly_PlaneSection() {} //======================================================================= //function : IntPoly_PlaneSection //purpose : //======================================================================= IntPoly_PlaneSection::IntPoly_PlaneSection(const TopoDS_Shape& S, const gp_Pln& P) { myShape = S; myTransform.SetTransformation(P.Position()); gp_Ax3 Ax0(gp_Pnt(0,0,0),gp_Dir(0,0,1)); myBackTransform.SetTransformation(P.Position(),Ax0); Section(); } //======================================================================= //function : Section //purpose : //======================================================================= void IntPoly_PlaneSection::Section() { TopExp_Explorer ex; Standard_Integer NbTrian,i,i1,i2,i3,Result; Standard_Real Big = Precision::Infinite(); Standard_Boolean Inter; //gp_Pnt Nod1,Nod2,Nod3; gp_Pnt2d BegPoint,EndPoint,OutPoint; TopLoc_Location Loc; Handle(Poly_Triangulation) Tr; myCpt = 0; for (ex.Init(myShape,TopAbs_FACE);ex.More();ex.Next()) { Tr = (BRep_Tool::Triangulation(TopoDS::Face(ex.Current()),Loc)); if (!Tr.IsNull()) { NbTrian = Tr->NbTriangles(); const Poly_Array1OfTriangle& TabTrian = Tr->Triangles(); const TColgp_Array1OfPnt& TabNodes = Tr->Nodes(); TColgp_Array1OfPnt TabTransfNodes(1,Tr->NbNodes()); for (i = 1;i <= Tr->NbNodes();i++) { if (!Loc.IsIdentity()) TabTransfNodes(i) = (TabNodes(i).Transformed(Loc.Transformation())) .Transformed(myTransform); else TabTransfNodes(i) = TabNodes(i).Transformed(myTransform); } for (i = 1;i <= NbTrian;i++) { TabTrian(i).Get(i1,i2,i3); Inter = Intersect(TabTransfNodes(i1), TabTransfNodes(i2), TabTransfNodes(i3), BegPoint,EndPoint); if (Inter) { if (myMapBegPoints.Contains(BegPoint)) { Standard_Integer Index = myMapBegPoints.FindIndex(BegPoint); Insert(myMapEndPoints.FindKey(Index),BegPoint,EndPoint); myCpt++; myMapBegPoints.Substitute(Index,gp_Pnt2d(Big,myCpt)); myMapEndPoints.Substitute(Index,gp_Pnt2d(Big,myCpt)); } else if (myMapEndPoints.Contains(EndPoint)) { Standard_Integer Index = myMapEndPoints.FindIndex(EndPoint); Insert(myMapBegPoints.FindKey(Index),EndPoint,BegPoint); myCpt++; myMapBegPoints.Substitute(Index,gp_Pnt2d(Big,myCpt)); myMapEndPoints.Substitute(Index,gp_Pnt2d(Big,myCpt)); } else { myMapBegPoints.Add(BegPoint); myMapEndPoints.Add(EndPoint); } } } } } Standard_Integer NbLinks = myMapBegPoints.Extent(); i = 1; while (i <= NbLinks) { if (!(Precision::IsInfinite((myMapBegPoints.FindKey(i)).X()))) { BegPoint = myMapBegPoints.FindKey(i); EndPoint = myMapEndPoints.FindKey(i); myCpt++; myMapBegPoints.Substitute(i,gp_Pnt2d(Big,myCpt)); myMapEndPoints.Substitute(i,gp_Pnt2d(Big,myCpt)); Result = Concat(BegPoint,EndPoint,OutPoint); if (Result == 2) ForwConstruction(OutPoint); else if (Result == 1) PrevConstruction(OutPoint); else { ForwConstruction(EndPoint); PrevConstruction(BegPoint); } } i++; } i = 1; while (i < mySection.Length()) { ConcatSection(mySection.ChangeValue(i),mySection.Length(),i+1); i++; } myNbEdges = mySection.Length(); } //======================================================================= //function : Intersect //purpose : Determines the 2 2D-points resulting of the intersection // of the triangle (Point1,Point2,Point3) by the plane //======================================================================= Standard_Boolean IntPoly_PlaneSection::Intersect(const gp_Pnt& Point1, const gp_Pnt& Point2, const gp_Pnt& Point3, gp_Pnt2d& OutPoint1, gp_Pnt2d& OutPoint2) { gp_Pnt Pt1 = Point1; gp_Pnt Pt2 = Point2; gp_Pnt Pt3 = Point3; Standard_Real z1 = Pt1.Z(); Standard_Real z2 = Pt2.Z(); Standard_Real z3 = Pt3.Z(); Standard_Boolean intersection = Standard_False; if ((z1 == 0) && (z2 == 0) && (z3 == 0)) return intersection; if ((z1 == 0) && (z2 == 0)) { intersection = Standard_True; OutPoint1.SetCoord(Pt1.X(),Pt1.Y()); OutPoint2.SetCoord(Pt2.X(),Pt2.Y()); return intersection; } if ((z2 == 0) && (z3 == 0)) { intersection = Standard_True; OutPoint1.SetCoord(Pt2.X(),Pt2.Y()); OutPoint2.SetCoord(Pt3.X(),Pt3.Y()); return intersection; } if ((z3 == 0) && (z1 == 0)) { intersection = Standard_True; OutPoint1.SetCoord(Pt3.X(),Pt3.Y()); OutPoint2.SetCoord(Pt1.X(),Pt1.Y()); return intersection; } if (z1 == 0) { if ((z2 < 0) && (z3 > 0)) intersection = Standard_True; if ((z2 > 0) && (z3 < 0)) { intersection = Standard_True; gp_Pnt Pt = Pt2; Pt2 = Pt3; Pt3 = Pt; } if (intersection) { Standard_Real u1 = Pt2.X(); Standard_Real v1 = Pt2.Y(); z1 = Pt2.Z(); Standard_Real u2 = Pt3.X(); Standard_Real v2 = Pt3.Y(); z2 = Pt3.Z(); Standard_Real U = u1 - z1 * (u2 - u1)/(z2 - z1); Standard_Real V = v1 - z1 * (v2 - v1)/(z2 - z1); OutPoint1.SetCoord(Pt1.X(),Pt1.Y()); OutPoint2.SetCoord(U,V); return intersection; } } else if (z2 == 0) { if ((z1 < 0) && (z3 > 0)) intersection = Standard_True; if ((z1 > 0) && (z3 < 0)) { intersection = Standard_True; gp_Pnt Pt = Pt1; Pt1 = Pt3; Pt3 = Pt; } if (intersection) { Standard_Real u1 = Pt1.X(); Standard_Real v1 = Pt1.Y(); z1 = Pt1.Z(); Standard_Real u2 = Pt3.X(); Standard_Real v2 = Pt3.Y(); z2 = Pt3.Z(); Standard_Real U = u1 - z1 * (u2 - u1)/(z2 - z1); Standard_Real V = v1 - z1 * (v2 - v1)/(z2 - z1); OutPoint1.SetCoord(Pt2.X(),Pt2.Y()); OutPoint2.SetCoord(U,V); return intersection; } } else if (z3 == 0) { if ((z2 < 0) && (z1 > 0)) intersection = Standard_True; if ((z2 > 0) && (z1 < 0)) { intersection = Standard_True; gp_Pnt Pt = Pt2; Pt2 = Pt1; Pt1 = Pt; } if (intersection) { Standard_Real u1 = Pt2.X(); Standard_Real v1 = Pt2.Y(); z1 = Pt2.Z(); Standard_Real u2 = Pt1.X(); Standard_Real v2 = Pt1.Y(); z2 = Pt1.Z(); Standard_Real U = u1 - z1 * (u2 - u1)/(z2 - z1); Standard_Real V = v1 - z1 * (v2 - v1)/(z2 - z1); OutPoint1.SetCoord(Pt3.X(),Pt3.Y()); OutPoint2.SetCoord(U,V); return intersection; } } if ((z1 < 0) && (z2 > 0)) intersection = Standard_True; if ((z1 > 0) && (z2 < 0)) { intersection = Standard_True; gp_Pnt Pt = Pt1; Pt1 = Pt2; Pt2 = Pt; } if (intersection) { Standard_Real u1 = Pt1.X(); Standard_Real v1 = Pt1.Y(); z1 = Pt1.Z(); Standard_Real u2 = Pt2.X(); Standard_Real v2 = Pt2.Y(); z2 = Pt2.Z(); Standard_Real U = u1 - z1 * (u2 - u1)/(z2 - z1); Standard_Real V = v1 - z1 * (v2 - v1)/(z2 - z1); OutPoint1.SetCoord(U,V); intersection = Standard_False; Pt1 = Point1; Pt2 = Point2; z1 = Pt1.Z(); z2 = Pt2.Z(); if ((z2 < 0) && (z3 > 0)) intersection = Standard_True; if ((z2 > 0) && (z3 < 0)) { intersection = Standard_True; gp_Pnt Pt = Pt2; Pt2 = Pt3; Pt3 = Pt; } if (intersection) { u1 = Pt2.X(); v1 = Pt2.Y(); z1 = Pt2.Z(); u2 = Pt3.X(); v2 = Pt3.Y(); z2 = Pt3.Z(); U = u1 - z1 * (u2 - u1)/(z2 - z1); V = v1 - z1 * (v2 - v1)/(z2 - z1); OutPoint2.SetCoord(U,V); return intersection; } else { intersection = Standard_True; Pt3 = Point3; z3 = Pt3.Z(); if ((z3 > 0) && (z1 < 0)) { gp_Pnt Pt = Pt3; Pt3 = Pt1; Pt1 = Pt; } u1 = Pt3.X(); v1 = Pt3.Y(); z1 = Pt3.Z(); u2 = Pt1.X(); v2 = Pt1.Y(); z2 = Pt1.Z(); U = u1 - z1 * (u2 - u1)/(z2 - z1); V = v1 - z1 * (v2 - v1)/(z2 - z1); OutPoint2.SetCoord(U,V); return intersection; } } else { if ((z2 < 0) && (z3 > 0)) intersection = Standard_True; if ((z2 > 0) && (z3 < 0)) { intersection = Standard_True; gp_Pnt Pt = Pt2; Pt2 = Pt3; Pt3 = Pt; } if (intersection) { Standard_Real u1 = Pt2.X(); Standard_Real v1 = Pt2.Y(); z1 = Pt2.Z(); Standard_Real u2 = Pt3.X(); Standard_Real v2 = Pt3.Y(); z2 = Pt3.Z(); Standard_Real U = u1 - z1 * (u2 - u1)/(z2 - z1); Standard_Real V = v1 - z1 * (v2 - v1)/(z2 - z1); OutPoint1.SetCoord(U,V); Pt3 = Point3; z3 = Pt3.Z(); if ((z3 > 0) && (z1 < 0)) { gp_Pnt Pt = Pt3; Pt3 = Pt1; Pt1 = Pt; } u1 = Pt3.X(); v1 = Pt3.Y(); z1 = Pt3.Z(); u2 = Pt1.X(); v2 = Pt1.Y(); z2 = Pt1.Z(); U = u1 - z1 * (u2 - u1)/(z2 - z1); V = v1 - z1 * (v2 - v1)/(z2 - z1); OutPoint2.SetCoord(U,V); return intersection; } } return intersection; } //======================================================================= //function : Insert //purpose : Sees whether OldPnt and NewPnt begins or ends a section // created before and adds the 2 others points. // If not, creates a section //======================================================================= void IntPoly_PlaneSection::Insert(const gp_Pnt2d& OldPnt, const gp_Pnt2d& ComPnt, const gp_Pnt2d& NewPnt) { Standard_Integer i = 0; Standard_Integer NbSection = mySection.Length(); Standard_Boolean IsInSection = Standard_False; while (i < NbSection) { i++; TColgp_SequenceOfPnt2d& CurSection = mySection.ChangeValue(i); if (IntPoly_Pnt2dHasher::IsEqual(OldPnt,CurSection.First())) { IsInSection = Standard_True; CurSection.Prepend(ComPnt); CurSection.Prepend(NewPnt); break; } if (IntPoly_Pnt2dHasher::IsEqual(OldPnt,CurSection.Last())) { IsInSection = Standard_True; CurSection.Append(ComPnt); CurSection.Append(NewPnt); break; } if (IntPoly_Pnt2dHasher::IsEqual(NewPnt,CurSection.First())) { IsInSection = Standard_True; CurSection.Prepend(ComPnt); CurSection.Prepend(OldPnt); break; } if (IntPoly_Pnt2dHasher::IsEqual(NewPnt,CurSection.Last())) { IsInSection = Standard_True; CurSection.Append(ComPnt); CurSection.Append(OldPnt); break; } } if (!(IsInSection)) { TColgp_SequenceOfPnt2d EmptySec; EmptySec.Append(OldPnt); EmptySec.Append(ComPnt); EmptySec.Append(NewPnt); mySection.Append(EmptySec); } } //======================================================================= //function : Concat //purpose : sees whether BegPnt or EndPnt begins or ends a section // created before, and returns the other point to continue // the construction // Returns 2 if the construction is 'Forward' // Returns 1 if the construction is 'Previous' // Returns 0 if not and creates a section //======================================================================= Standard_Integer IntPoly_PlaneSection::Concat(const gp_Pnt2d& BegPnt, const gp_Pnt2d& EndPnt, gp_Pnt2d& OutPnt) { Standard_Integer i = 0; Standard_Integer NbSection = mySection.Length(); Standard_Integer ConcatIdx = 0; while (i < NbSection) { i++; TColgp_SequenceOfPnt2d& CurSection = mySection.ChangeValue(i); if (IntPoly_Pnt2dHasher::IsEqual(BegPnt,CurSection.First())) { ConcatIdx = 1; myIndex = i; CurSection.Prepend(EndPnt); OutPnt = EndPnt; break; } if (IntPoly_Pnt2dHasher::IsEqual(BegPnt,CurSection.Last())) { ConcatIdx = 2; myIndex = i; CurSection.Append(EndPnt); OutPnt = EndPnt; break; } if (IntPoly_Pnt2dHasher::IsEqual(EndPnt,CurSection.First())) { ConcatIdx = 1; myIndex = i; CurSection.Prepend(BegPnt); OutPnt = BegPnt; break; } if (IntPoly_Pnt2dHasher::IsEqual(EndPnt,CurSection.Last())) { ConcatIdx = 2; myIndex = i; CurSection.Append(BegPnt); OutPnt = BegPnt; break; } } if (ConcatIdx == 0) { TColgp_SequenceOfPnt2d EmptySec; EmptySec.Append(BegPnt); EmptySec.Append(EndPnt); mySection.Append(EmptySec); NbSection++; myIndex = NbSection; } return ConcatIdx; } //======================================================================= //function : ConcatSection //purpose : Sees whether Section begins or ends another one in mySection, // from the rank 'Index' to the last one 'NbSection' //======================================================================= void IntPoly_PlaneSection::ConcatSection(TColgp_SequenceOfPnt2d& Section, const Standard_Integer NbSection, const Standard_Integer Index) { Standard_Integer j; Standard_Integer i = Index; gp_Pnt2d BegPnt = Section.First(); gp_Pnt2d EndPnt = Section.Last(); while (i <= NbSection) { TColgp_SequenceOfPnt2d& CurSection = mySection.ChangeValue(i); Standard_Integer CurSection_Length = CurSection.Length(); if (IntPoly_Pnt2dHasher::IsEqual(BegPnt,CurSection.First())) { for (j = 2;j <= CurSection_Length;j++) Section.Prepend(CurSection.Value(j)); mySection.Remove(i); ConcatSection(Section,NbSection-1,Index); break; } else if (IntPoly_Pnt2dHasher::IsEqual(BegPnt,CurSection.Last())) { for (j = CurSection_Length-1;j >= 1;j--) Section.Prepend(CurSection.Value(j)); mySection.Remove(i); ConcatSection(Section,NbSection-1,Index); break; } else if (IntPoly_Pnt2dHasher::IsEqual(EndPnt,CurSection.First())) { for (j = 2;j <= CurSection_Length;j++) Section.Append(CurSection.Value(j)); mySection.Remove(i); ConcatSection(Section,NbSection-1,Index); break; } else if (IntPoly_Pnt2dHasher::IsEqual(EndPnt,CurSection.Last())) { for (j = CurSection_Length-1;j >= 1;j--) Section.Append(CurSection.Value(j)); mySection.Remove(i); ConcatSection(Section,NbSection-1,Index); break; } i++; } } //======================================================================= //function : ForwContruction //purpose : Builds a section from Point in this way // ___ ___ ___ ___ // <---/__/--/__/--/__/--/__/--Point //======================================================================= void IntPoly_PlaneSection::ForwConstruction(const gp_Pnt2d& Point) { if (myMapBegPoints.Contains(Point)) { Standard_Integer Index = myMapBegPoints.FindIndex(Point); gp_Pnt2d Pnt = myMapEndPoints.FindKey(Index); (mySection.ChangeValue(myIndex)).Append(Pnt); Standard_Real Big = Precision::Infinite(); myCpt++; myMapBegPoints.Substitute(Index,gp_Pnt2d(Big,myCpt)); myMapEndPoints.Substitute(Index,gp_Pnt2d(Big,myCpt)); ForwConstruction(Pnt); } } //======================================================================= //function : PrevContruction //purpose : Builds a section from Point in this way // ___ ___ ___ ___ // Point--/__/--/__/--/__/--/__/---> //======================================================================= void IntPoly_PlaneSection::PrevConstruction(const gp_Pnt2d& Point) { if (myMapEndPoints.Contains(Point)) { Standard_Integer Index = myMapEndPoints.FindIndex(Point); gp_Pnt2d Pnt = myMapBegPoints.FindKey(Index); (mySection.ChangeValue(myIndex)).Prepend(Pnt); Standard_Real Big = Precision::Infinite(); myCpt++; myMapBegPoints.Substitute(Index,gp_Pnt2d(Big,myCpt)); myMapEndPoints.Substitute(Index,gp_Pnt2d(Big,myCpt)); PrevConstruction(Pnt); } } //======================================================================= //function : NbEdges //purpose : Returns the final number of edges in the section //======================================================================= Standard_Integer IntPoly_PlaneSection::NbEdges() { return myNbEdges; } //======================================================================= //function : Edge //purpose : Builds the edges of the section //======================================================================= TopoDS_Edge IntPoly_PlaneSection::Edge(const Standard_Integer Index) { const TColgp_SequenceOfPnt2d& CurSection = mySection.ChangeValue(Index); Standard_Integer NbPoints = CurSection.Length(); TColgp_Array1OfPnt TabPnt(1,NbPoints); gp_Pnt CurPoint; for (Standard_Integer i = 1 ; i <= NbPoints ; i++) { CurPoint.SetX((CurSection.Value(i)).X()); CurPoint.SetY((CurSection.Value(i)).Y()); CurPoint.SetZ(0); TabPnt.SetValue(i,CurPoint.Transformed(myBackTransform)); } Handle(Poly_Polygon3D) Pol = new Poly_Polygon3D(TabPnt); TopoDS_Edge Edge; BRep_Builder B; B.MakeEdge(Edge,Pol); return Edge; }