1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File: GEOMAlgo_FinderShapeOn1.cxx
24 // Created: Fri Mar 4 10:31:06 2005
25 // Author: Peter KURNEV
27 #include <GEOMAlgo_FinderShapeOn1.hxx>
31 #include <Precision.hxx>
32 #include <TColStd_Array1OfInteger.hxx>
33 #include <TColStd_MapOfInteger.hxx>
35 #include <gp_Trsf.hxx>
36 #include <gp_Cylinder.hxx>
39 #include <TColgp_Array1OfPnt.hxx>
41 #include <Poly_Array1OfTriangle.hxx>
42 #include <Poly_Triangle.hxx>
43 #include <Poly_PolygonOnTriangulation.hxx>
44 #include <Poly_Triangulation.hxx>
45 #include <Poly_Polygon3D.hxx>
47 #include <Geom_Curve.hxx>
48 #include <Geom_Surface.hxx>
49 #include <GeomAdaptor_Surface.hxx>
50 #include <GeomAbs_SurfaceType.hxx>
51 #include <GeomAdaptor_Curve.hxx>
52 #include <GeomAbs_CurveType.hxx>
54 #include <TopAbs_State.hxx>
56 #include <TopLoc_Location.hxx>
58 #include <TopoDS_Shape.hxx>
59 #include <TopoDS_Vertex.hxx>
60 #include <TopoDS_Face.hxx>
61 #include <TopoDS_Edge.hxx>
64 #include <TopExp_Explorer.hxx>
66 #include <TopTools_IndexedMapOfShape.hxx>
68 #include <BRep_Tool.hxx>
69 #include <BRepLib_MakeEdge.hxx>
71 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
72 #include <GEOMAlgo_SurfaceTools.hxx>
73 #include <GEOMAlgo_StateCollector.hxx>
74 #include <GEOMAlgo_AlgoTools.hxx>
75 #include <GEOMAlgo_PassKey.hxx>
76 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
77 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
80 //=======================================================================
81 //function : GEOMAlgo_FinderShapeOn1
83 //=======================================================================
84 GEOMAlgo_FinderShapeOn1::GEOMAlgo_FinderShapeOn1()
89 myShapeType=TopAbs_VERTEX;
90 myState=GEOMAlgo_ST_UNKNOWN;
94 //=======================================================================
97 //=======================================================================
98 GEOMAlgo_FinderShapeOn1::~GEOMAlgo_FinderShapeOn1()
101 //=======================================================================
102 //function : SetSurface
104 //=======================================================================
105 void GEOMAlgo_FinderShapeOn1::SetSurface(const Handle(Geom_Surface)& aS)
109 //=======================================================================
112 //=======================================================================
113 const Handle(Geom_Surface)& GEOMAlgo_FinderShapeOn1::Surface() const
117 //=======================================================================
118 //function : SetShapeType
120 //=======================================================================
121 void GEOMAlgo_FinderShapeOn1::SetShapeType(const TopAbs_ShapeEnum aType)
125 //=======================================================================
126 //function : ShapeType
128 //=======================================================================
129 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn1::ShapeType()const
133 //=======================================================================
134 //function : SetState
136 //=======================================================================
137 void GEOMAlgo_FinderShapeOn1::SetState(const GEOMAlgo_State aState)
141 //=======================================================================
144 //=======================================================================
145 GEOMAlgo_State GEOMAlgo_FinderShapeOn1::State() const
149 //=======================================================================
150 //function : SetNbPntsMin
152 //=======================================================================
153 void GEOMAlgo_FinderShapeOn1::SetNbPntsMin(const Standard_Integer aNb)
157 //=======================================================================
158 //function : NbPntsMin
160 //=======================================================================
161 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMin()const
165 //=======================================================================
166 //function : SetNbPntsMax
168 //=======================================================================
169 void GEOMAlgo_FinderShapeOn1::SetNbPntsMax(const Standard_Integer aNb)
173 //=======================================================================
174 //function : NbPntsMax
176 //=======================================================================
177 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMax()const
181 //=======================================================================
184 //=======================================================================
185 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn1::MSS() const
189 //=======================================================================
192 //=======================================================================
193 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn1::Shapes() const
195 Standard_Integer i, aNb;
196 TopTools_ListOfShape* pL;
198 pL=(TopTools_ListOfShape*) &myLS;
202 for (i=1; i<=aNb; ++i) {
203 const TopoDS_Shape& aS=myMSS.FindKey(i);
204 if (aS.ShapeType()==myShapeType) {
210 //=======================================================================
213 //=======================================================================
214 void GEOMAlgo_FinderShapeOn1::Perform()
226 // Initialize the context
227 GEOMAlgo_ShapeAlgo::Perform();
234 if (myShapeType==TopAbs_VERTEX) {
243 if (myShapeType==TopAbs_EDGE) {
252 if (myShapeType==TopAbs_FACE) {
260 //=======================================================================
261 //function : ProcessVertices
263 //=======================================================================
264 void GEOMAlgo_FinderShapeOn1::ProcessVertices()
268 Standard_Boolean bIsConformState;
269 Standard_Integer i, aNb;
271 TopTools_IndexedMapOfShape aM;
274 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
276 for (i=1; i<=aNb; ++i) {
277 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
278 aP=BRep_Tool::Pnt(aV);
280 aSt = GetPointState( aP );
281 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
283 if (myShapeType==TopAbs_VERTEX){
284 if (bIsConformState) {
288 else if (bIsConformState || aSt==TopAbs_ON) {
293 //=======================================================================
294 //function : ProcessEdges
296 //=======================================================================
297 void GEOMAlgo_FinderShapeOn1::ProcessEdges()
301 Standard_Boolean bIsConformState, bIsToBreak;
302 Standard_Integer i, aNb, iCnt;
304 TopTools_IndexedMapOfShape aM;
305 TopExp_Explorer aExp;
306 GEOMAlgo_ListIteratorOfListOfPnt aIt;
307 GeomAbs_SurfaceType aType1;
309 aType1=myGAS.GetType();
311 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
313 bIsConformState=Standard_False;
316 for (i=1; i<=aNb; ++i) {
317 GEOMAlgo_ListOfPnt aLP;
318 GEOMAlgo_StateCollector aSC;
320 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
322 aExp.Init(aE, TopAbs_VERTEX);
323 for (; aExp.More(); aExp.Next()) {
324 const TopoDS_Shape& aV=aExp.Current();
326 bIsConformState=myMSS.Contains(aV);
327 if (!bIsConformState) {
328 break;// vertex has non-conformed state
331 aSt=myMSS.FindFromKey(aV);
332 aSC.AppendState(aSt);
336 if (!bIsConformState) {
337 continue; // vertex has non-conformed state,skip edge
340 if (BRep_Tool::Degenerated(aE)) {
345 if (myState==GEOMAlgo_ST_ON && aType1==GeomAbs_Sphere) {
346 Standard_Real aT1, aT2;
347 Handle(Geom_Curve) aC;
348 GeomAdaptor_Curve aGAC;
349 GeomAbs_CurveType aType2;
351 aC=BRep_Tool::Curve(aE, aT1, aT2);
354 aType2=aGAC.GetType();
355 if (aType2==GeomAbs_Line) {
360 InnerPoints(aE, aLP);
365 bIsConformState=Standard_True;
367 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
369 if (iCnt > myNbPntsMax) {
374 const gp_Pnt& aP=aIt.Value();
375 aSt = GetPointState( aP );
376 bIsToBreak=aSC.AppendState(aSt);
384 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
385 if (myShapeType==TopAbs_EDGE) {
386 if (bIsConformState) {
390 else if (bIsConformState || aSt==TopAbs_ON) {
393 } // for (i=1; i<=aNb; ++i) next edge
395 //=======================================================================
396 //function : ProcessFaces
398 //=======================================================================
399 void GEOMAlgo_FinderShapeOn1::ProcessFaces()
403 Standard_Boolean bIsConformState, bIsToBreak;
404 Standard_Integer i, aNbF, iCnt;
406 TopTools_IndexedMapOfShape aM;
407 TopExp_Explorer aExp;
408 GEOMAlgo_ListIteratorOfListOfPnt aIt;
409 GeomAbs_SurfaceType aType1, aType2;
411 aType1=myGAS.GetType();
413 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
415 for (i=1; i<=aNbF; ++i) {
416 GEOMAlgo_StateCollector aSC;
417 GEOMAlgo_ListOfPnt aLP;
419 const TopoDS_Face& aF=TopoDS::Face(aM(i));
421 if (myState==GEOMAlgo_ST_ON) {
422 Handle(Geom_Surface) aS;
423 GeomAdaptor_Surface aGAS;
425 aS=BRep_Tool::Surface(aF);
427 aType2=aGAS.GetType();
428 if (aType2!=aType1) {
433 bIsConformState=Standard_False;
435 aExp.Init(aF, TopAbs_EDGE);
436 for (; aExp.More(); aExp.Next()) {
437 const TopoDS_Shape& aE=aExp.Current();
438 bIsConformState=myMSS.Contains(aE);
439 if (!bIsConformState) {
440 break;// edge has non-conformed state
443 aSt=myMSS.FindFromKey(aE);
444 aSC.AppendState(aSt);
448 if (!bIsConformState) {
449 continue; // edge has non-conformed state,skip face
452 InnerPoints(aF, aLP);
457 bIsConformState=Standard_True;
459 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
461 if (iCnt > myNbPntsMax) {
466 const gp_Pnt& aP=aIt.Value();
467 aSt = GetPointState( aP );
468 bIsToBreak=aSC.AppendState(aSt);
476 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
477 if (myShapeType==TopAbs_FACE) {
478 if (bIsConformState) {
482 else if (bIsConformState || aSt==TopAbs_ON) {
485 }// for (i=1; i<=aNb; ++i) next face
487 //=======================================================================
488 //function : ProcessSolids
490 //=======================================================================
491 void GEOMAlgo_FinderShapeOn1::ProcessSolids()
495 Standard_Boolean bIsConformState;
496 Standard_Integer i, aNbS, j, aNbF;
497 TopTools_IndexedMapOfShape aM, aMF;
500 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
502 for (i=1; i<=aNbS; ++i) {
503 GEOMAlgo_StateCollector aSC;
505 const TopoDS_Shape& aSd=aM(i);
507 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
509 bIsConformState=Standard_False;
512 for (j=1; j<=aNbF; ++j) {
513 const TopoDS_Shape& aF=aMF(j);
514 bIsConformState=myMSS.Contains(aF);
515 if (!bIsConformState) {
516 break;// face has non-conformed state
519 aSt=myMSS.FindFromKey(aF);
520 aSC.AppendState(aSt);
524 if (!bIsConformState) {
525 continue; // face has non-conformed state,skip solid
530 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
531 if (bIsConformState) {
537 //=======================================================================
538 //function : InnerPoints
540 //=======================================================================
541 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Face& aF,
542 GEOMAlgo_ListOfPnt& aLP)
546 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
547 TopLoc_Location aLoc;
548 Handle(Poly_Triangulation) aTRF;
549 TColStd_MapOfInteger aMBN;
550 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
551 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
556 aTRF=BRep_Tool::Triangulation(aF, aLoc);
558 if (!GEOMAlgo_AlgoTools::BuildTriangulation(aF)) {
559 myWarningStatus=20; // no triangulation found
562 aTRF=BRep_Tool::Triangulation(aF, aLoc);
565 const gp_Trsf& aTrsf=aLoc.Transformation();
566 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
567 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
569 // map link/nbtriangles
572 for (j=j1; j<=j2; ++j) {
573 const Poly_Triangle& aTr=aTrs(j);
574 aTr.Get(n[0], n[1], n[2]);
576 for (k=0; k<3; ++k) {
577 GEOMAlgo_PassKey aPK;
579 aPK.SetIds(n[k], n[k+1]);
580 if (aMPKI.IsBound(aPK)) {
581 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
590 // boundary nodes aMBN
591 aNbLinks=aMPKI.Extent();
592 aIt.Initialize(aMPKI);
593 for (; aIt.More(); aIt.Next()) {
596 const GEOMAlgo_PassKey& aPK=aIt.Key();
598 aNx=(Standard_Integer)aPK.Id(1);
600 aNx=(Standard_Integer)aPK.Id(2);
605 // inner nodes=all_nodes - boundary_nodes
608 for (j=j1; j<=j2; ++j) {
609 if (!aMBN.Contains(j)) {
610 aP=aNodes(j).Transformed(aTrsf);
617 if (!aNb && myNbPntsMin) {
618 // try to fill it yourself
619 Standard_Boolean bIsDone;
620 Standard_Integer aN1, aN2;
621 Handle(Geom_Surface) aS;
622 GeomAdaptor_Surface aGAS;
623 GeomAbs_SurfaceType aType;
625 aS=BRep_Tool::Surface(aF);
627 aType=aGAS.GetType();
628 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
630 aNbLinks=aMPKI.Extent();
631 aIt.Initialize(aMPKI);
632 for (; aIt.More(); aIt.Next()) {
635 // take the first having occurred inner link
637 const GEOMAlgo_PassKey& aPK=aIt.Key();
639 aN1=(Standard_Integer)aPK.Id(1);
640 aN2=(Standard_Integer)aPK.Id(2);
642 aP1=aNodes(aN1).Transformed(aTrsf);
643 aP2=aNodes(aN2).Transformed(aTrsf);
645 if (aType==GeomAbs_Cylinder) {
648 aCyl=aGAS.Cylinder();
649 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, myTolerance)) {
654 BRepLib_MakeEdge aBME(aP1, aP2);
655 bIsDone=aBME.IsDone();
657 myErrorStatus=30; //can not obtain the line from the link
661 const TopoDS_Shape& aSx=aBME.Shape();
662 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
664 InnerPoints(aE, myNbPntsMin, aLP);
667 }// for (; aIt.More(); aIt.Next())
668 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
669 }// if (!aNb && myNbPntsMin) {
671 //=======================================================================
672 //function : InnerPoints
674 //=======================================================================
675 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
676 GEOMAlgo_ListOfPnt& aLP)
678 Standard_Integer aNbPntsMin;
684 InnerPoints(aE, aNbPntsMin, aLP);
686 //=======================================================================
687 //function : InnerPoints
689 //=======================================================================
690 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
691 const Standard_Integer aNbPntsMin,
692 GEOMAlgo_ListOfPnt& aLP)
694 Standard_Boolean bInf1, bInf2;
695 Standard_Integer j, aNbT;
696 Standard_Real dT, aT, aT1, aT2;
698 Handle(Geom_Curve) aC3D;
700 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
705 bInf1=Precision::IsNegativeInfinite(aT1);
706 bInf2=Precision::IsPositiveInfinite(aT2);
707 if (bInf1 || bInf2) {
713 for (j=1; j<aNbT; ++j) {
720 //=======================================================================
721 //function : CheckData
723 //=======================================================================
724 void GEOMAlgo_FinderShapeOn1::CheckData()
728 if(mySurface.IsNull()) {
729 myErrorStatus=10; // mySurface=NULL
733 if (myShape.IsNull()) {
734 myErrorStatus=11; // myShape=NULL
738 if (!(myShapeType==TopAbs_VERTEX ||
739 myShapeType==TopAbs_EDGE ||
740 myShapeType==TopAbs_FACE ||
741 myShapeType==TopAbs_SOLID)) {
742 myErrorStatus=12; // unallowed subshape type
746 if (myState==GEOMAlgo_ST_UNKNOWN ||
747 myState==GEOMAlgo_ST_INOUT) {
748 myErrorStatus=13; // unallowed state type
752 GeomAbs_SurfaceType aType;
754 myGAS.Load(mySurface);
755 aType=myGAS.GetType();
756 if (!(aType==GeomAbs_Plane ||
757 aType==GeomAbs_Cylinder ||
758 aType==GeomAbs_Sphere)) {
759 myErrorStatus=14; // unallowed surface type
763 //=======================================================================
764 //function : GetPointState
766 //=======================================================================
768 TopAbs_State GEOMAlgo_FinderShapeOn1::GetPointState(const gp_Pnt& aP)
771 GEOMAlgo_SurfaceTools::GetState(aP, myGAS, myTolerance, aSt);
779 // 10 -mySurface=NULL
781 // 12 -unallowed type of subshapes
782 // 13 -unallowed state
783 // 14 -unallowed surface type
784 // 15 -unallowed surface type
785 // 20- no triangulation found
786 // 30- can not obtain the line from the link