1 // Copyright (C) 2007-2010 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.
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
28 #include <GEOMAlgo_FinderShapeOn1.ixx>
32 #include <Precision.hxx>
33 #include <TColStd_Array1OfInteger.hxx>
34 #include <TColStd_MapOfInteger.hxx>
36 #include <gp_Trsf.hxx>
37 #include <gp_Cylinder.hxx>
40 #include <TColgp_Array1OfPnt.hxx>
42 #include <Poly_Array1OfTriangle.hxx>
43 #include <Poly_Triangle.hxx>
44 #include <Poly_PolygonOnTriangulation.hxx>
45 #include <Poly_Triangulation.hxx>
46 #include <Poly_Polygon3D.hxx>
48 #include <Geom_Curve.hxx>
49 #include <Geom_Surface.hxx>
50 #include <GeomAdaptor_Surface.hxx>
51 #include <GeomAbs_SurfaceType.hxx>
52 #include <GeomAdaptor_Curve.hxx>
53 #include <GeomAbs_CurveType.hxx>
55 #include <TopAbs_State.hxx>
57 #include <TopLoc_Location.hxx>
59 #include <TopoDS_Shape.hxx>
60 #include <TopoDS_Vertex.hxx>
61 #include <TopoDS_Face.hxx>
62 #include <TopoDS_Edge.hxx>
65 #include <TopExp_Explorer.hxx>
67 #include <TopTools_IndexedMapOfShape.hxx>
69 #include <BRep_Tool.hxx>
70 #include <BRepLib_MakeEdge.hxx>
72 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
74 #include <GEOMAlgo_SurfaceTools.hxx>
75 #include <GEOMAlgo_StateCollector.hxx>
76 #include <GEOMAlgo_FinderShapeOn.hxx>
78 #include <GEOMAlgo_PassKey.hxx>
79 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
80 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
82 //=======================================================================
83 //function : GEOMAlgo_FinderShapeOn1
85 //=======================================================================
86 GEOMAlgo_FinderShapeOn1::GEOMAlgo_FinderShapeOn1()
91 myShapeType=TopAbs_VERTEX;
92 myState=GEOMAlgo_ST_UNKNOWN;
96 //=======================================================================
99 //=======================================================================
100 GEOMAlgo_FinderShapeOn1::~GEOMAlgo_FinderShapeOn1()
103 //=======================================================================
104 //function : SetSurface
106 //=======================================================================
107 void GEOMAlgo_FinderShapeOn1::SetSurface(const Handle(Geom_Surface)& aS)
111 //=======================================================================
114 //=======================================================================
115 const Handle(Geom_Surface)& GEOMAlgo_FinderShapeOn1::Surface() const
119 //=======================================================================
120 //function : SetShapeType
122 //=======================================================================
123 void GEOMAlgo_FinderShapeOn1::SetShapeType(const TopAbs_ShapeEnum aType)
127 //=======================================================================
128 //function : ShapeType
130 //=======================================================================
131 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn1::ShapeType()const
135 //=======================================================================
136 //function : SetState
138 //=======================================================================
139 void GEOMAlgo_FinderShapeOn1::SetState(const GEOMAlgo_State aState)
143 //=======================================================================
146 //=======================================================================
147 GEOMAlgo_State GEOMAlgo_FinderShapeOn1::State() const
151 //=======================================================================
152 //function : SetNbPntsMin
154 //=======================================================================
155 void GEOMAlgo_FinderShapeOn1::SetNbPntsMin(const Standard_Integer aNb)
159 //=======================================================================
160 //function : NbPntsMin
162 //=======================================================================
163 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMin()const
167 //=======================================================================
168 //function : SetNbPntsMax
170 //=======================================================================
171 void GEOMAlgo_FinderShapeOn1::SetNbPntsMax(const Standard_Integer aNb)
175 //=======================================================================
176 //function : NbPntsMax
178 //=======================================================================
179 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMax()const
183 //=======================================================================
186 //=======================================================================
187 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn1::MSS() const
191 //=======================================================================
194 //=======================================================================
195 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn1::Shapes() const
197 Standard_Integer i, aNb;
198 TopTools_ListOfShape* pL;
200 pL=(TopTools_ListOfShape*) &myLS;
204 for (i=1; i<=aNb; ++i) {
205 const TopoDS_Shape& aS=myMSS.FindKey(i);
206 if (aS.ShapeType()==myShapeType) {
212 //=======================================================================
215 //=======================================================================
216 void GEOMAlgo_FinderShapeOn1::Perform()
233 if (myShapeType==TopAbs_VERTEX) {
242 if (myShapeType==TopAbs_EDGE) {
251 if (myShapeType==TopAbs_FACE) {
259 //=======================================================================
260 //function : ProcessVertices
262 //=======================================================================
263 void GEOMAlgo_FinderShapeOn1::ProcessVertices()
267 Standard_Boolean bIsConformState;
268 Standard_Integer i, aNb;
270 TopTools_IndexedMapOfShape aM;
273 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
275 for (i=1; i<=aNb; ++i) {
276 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
277 aP=BRep_Tool::Pnt(aV);
279 aSt = GetPointState( aP );
280 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
282 if (myShapeType==TopAbs_VERTEX){
283 if (bIsConformState) {
287 else if (bIsConformState || aSt==TopAbs_ON) {
292 //=======================================================================
293 //function : ProcessEdges
295 //=======================================================================
296 void GEOMAlgo_FinderShapeOn1::ProcessEdges()
300 Standard_Boolean bIsConformState, bIsToBreak;
301 Standard_Integer i, aNb, iCnt;
303 TopTools_IndexedMapOfShape aM;
304 TopExp_Explorer aExp;
305 GEOMAlgo_ListIteratorOfListOfPnt aIt;
306 GeomAbs_SurfaceType aType1;
308 aType1=myGAS.GetType();
310 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
312 for (i=1; i<=aNb; ++i) {
313 GEOMAlgo_ListOfPnt aLP;
314 GEOMAlgo_StateCollector aSC;
316 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
318 aExp.Init(aE, TopAbs_VERTEX);
319 for (; aExp.More(); aExp.Next()) {
320 const TopoDS_Shape& aV=aExp.Current();
322 bIsConformState=myMSS.Contains(aV);
323 if (!bIsConformState) {
324 break;// vertex has non-conformed state
327 aSt=myMSS.FindFromKey(aV);
328 aSC.AppendState(aSt);
332 if (!bIsConformState) {
333 continue; // vertex has non-conformed state,skip edge
336 if (BRep_Tool::Degenerated(aE)) {
341 if (myState==GEOMAlgo_ST_ON && aType1==GeomAbs_Sphere) {
342 Standard_Real aT1, aT2;
343 Handle(Geom_Curve) aC;
344 GeomAdaptor_Curve aGAC;
345 GeomAbs_CurveType aType2;
347 aC=BRep_Tool::Curve(aE, aT1, aT2);
350 aType2=aGAC.GetType();
351 if (aType2==GeomAbs_Line) {
356 InnerPoints(aE, aLP);
361 bIsConformState=Standard_True;
363 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
365 if (iCnt > myNbPntsMax) {
370 const gp_Pnt& aP=aIt.Value();
371 aSt = GetPointState( aP );
372 bIsToBreak=aSC.AppendState(aSt);
380 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
381 if (myShapeType==TopAbs_EDGE) {
382 if (bIsConformState) {
386 else if (bIsConformState || aSt==TopAbs_ON) {
389 } // for (i=1; i<=aNb; ++i) next edge
391 //=======================================================================
392 //function : ProcessFaces
394 //=======================================================================
395 void GEOMAlgo_FinderShapeOn1::ProcessFaces()
399 Standard_Boolean bIsConformState, bIsToBreak;
400 Standard_Integer i, aNbF, iCnt;
402 TopTools_IndexedMapOfShape aM;
403 TopExp_Explorer aExp;
404 GEOMAlgo_ListIteratorOfListOfPnt aIt;
405 GeomAbs_SurfaceType aType1, aType2;
407 aType1=myGAS.GetType();
409 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
411 for (i=1; i<=aNbF; ++i) {
412 GEOMAlgo_StateCollector aSC;
413 GEOMAlgo_ListOfPnt aLP;
415 const TopoDS_Face& aF=TopoDS::Face(aM(i));
417 if (myState==GEOMAlgo_ST_ON) {
418 Handle(Geom_Surface) aS;
419 GeomAdaptor_Surface aGAS;
421 aS=BRep_Tool::Surface(aF);
423 aType2=aGAS.GetType();
424 if (aType2!=aType1) {
429 aExp.Init(aF, TopAbs_EDGE);
430 for (; aExp.More(); aExp.Next()) {
431 const TopoDS_Shape& aE=aExp.Current();
432 bIsConformState=myMSS.Contains(aE);
433 if (!bIsConformState) {
434 break;// edge has non-conformed state
437 aSt=myMSS.FindFromKey(aE);
438 aSC.AppendState(aSt);
442 if (!bIsConformState) {
443 continue; // edge has non-conformed state,skip face
446 InnerPoints(aF, aLP);
451 bIsConformState=Standard_True;
453 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
455 if (iCnt > myNbPntsMax) {
460 const gp_Pnt& aP=aIt.Value();
461 aSt = GetPointState( aP );
462 bIsToBreak=aSC.AppendState(aSt);
470 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
471 if (myShapeType==TopAbs_FACE) {
472 if (bIsConformState) {
476 else if (bIsConformState || aSt==TopAbs_ON) {
479 }// for (i=1; i<=aNb; ++i) next face
481 //=======================================================================
482 //function : ProcessSolids
484 //=======================================================================
485 void GEOMAlgo_FinderShapeOn1::ProcessSolids()
489 Standard_Boolean bIsConformState;
490 Standard_Integer i, aNbS, j, aNbF;
491 TopTools_IndexedMapOfShape aM, aMF;
494 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
496 for (i=1; i<=aNbS; ++i) {
497 GEOMAlgo_StateCollector aSC;
499 const TopoDS_Shape& aSd=aM(i);
501 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
503 for (j=1; j<=aNbF; ++j) {
504 const TopoDS_Shape& aF=aMF(j);
505 bIsConformState=myMSS.Contains(aF);
506 if (!bIsConformState) {
507 break;// face has non-conformed state
510 aSt=myMSS.FindFromKey(aF);
511 aSC.AppendState(aSt);
515 if (!bIsConformState) {
516 continue; // face has non-conformed state,skip solid
521 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
522 if (bIsConformState) {
528 //=======================================================================
529 //function : InnerPoints
531 //=======================================================================
532 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Face& aF,
533 GEOMAlgo_ListOfPnt& aLP)
537 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
538 TopLoc_Location aLoc;
539 Handle(Poly_Triangulation) aTRF;
540 TColStd_MapOfInteger aMBN;
541 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
542 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
547 aTRF=BRep_Tool::Triangulation(aF, aLoc);
549 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
550 myWarningStatus=20; // no triangulation found
553 aTRF=BRep_Tool::Triangulation(aF, aLoc);
556 const gp_Trsf& aTrsf=aLoc.Transformation();
557 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
558 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
560 // map link/nbtriangles
563 for (j=j1; j<=j2; ++j) {
564 const Poly_Triangle& aTr=aTrs(j);
565 aTr.Get(n[0], n[1], n[2]);
567 for (k=0; k<3; ++k) {
568 GEOMAlgo_PassKey aPK;
570 aPK.SetIds(n[k], n[k+1]);
571 if (aMPKI.IsBound(aPK)) {
572 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
581 // boundary nodes aMBN
582 aNbLinks=aMPKI.Extent();
583 aIt.Initialize(aMPKI);
584 for (; aIt.More(); aIt.Next()) {
587 const GEOMAlgo_PassKey& aPK=aIt.Key();
591 pIds=(Standard_Integer*)aPK.Key();
592 for (k=1; k<3; ++k) {
593 aNx=*(pIds+aNbMax-k);
597 aNx=(Standard_Integer)aPK.Id(1);
599 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 occured inner link
637 const GEOMAlgo_PassKey& aPK=aIt.Key();
641 pIds=(Standard_Integer*)aPK.Key();
642 aN1=*(pIds+aNbMax-1);
643 aN2=*(pIds+aNbMax-2);
646 aN1=(Standard_Integer)aPK.Id(1);
647 aN2=(Standard_Integer)aPK.Id(2);
649 aP1=aNodes(aN1).Transformed(aTrsf);
650 aP2=aNodes(aN2).Transformed(aTrsf);
652 if (aType==GeomAbs_Cylinder) {
653 Standard_Real aTolSM;
656 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
657 aCyl=aGAS.Cylinder();
658 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
663 BRepLib_MakeEdge aBME(aP1, aP2);
664 bIsDone=aBME.IsDone();
666 myErrorStatus=30; //can not obtain the line fron the link
670 const TopoDS_Shape& aSx=aBME.Shape();
671 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
673 InnerPoints(aE, myNbPntsMin, aLP);
676 }// for (; aIt.More(); aIt.Next())
677 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
678 }// if (!aNb && myNbPntsMin) {
680 //=======================================================================
681 //function : InnerPoints
683 //=======================================================================
684 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
685 GEOMAlgo_ListOfPnt& aLP)
689 Standard_Integer j, aNbNodes, aIndex, aNb;
690 Handle(Poly_PolygonOnTriangulation) aPTE;
691 Handle(Poly_Triangulation) aTRE;
692 TopLoc_Location aLoc;
696 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
697 if (aTRE.IsNull() || aPTE.IsNull()) {
698 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
700 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
701 myErrorStatus=20; // no triangulation found
704 aPE = BRep_Tool::Polygon3D(aE, aLoc);
706 const gp_Trsf& aTrsf=aLoc.Transformation();
707 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
709 aNbNodes=aPE->NbNodes();
710 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
711 for (j=low+1; j<up; ++j) {
712 aP=aNodes(j).Transformed(aTrsf);
717 const gp_Trsf& aTrsf=aLoc.Transformation();
718 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
720 aNbNodes=aPTE->NbNodes();
721 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
722 for (j=2; j<aNbNodes; ++j) {
724 aP=aNodes(aIndex).Transformed(aTrsf);
730 if (!aNb && myNbPntsMin) {
731 // try to fill it yourself
732 InnerPoints(aE, myNbPntsMin, aLP);
736 //=======================================================================
737 //function : InnerPoints
739 //=======================================================================
740 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
741 const Standard_Integer aNbPntsMin,
742 GEOMAlgo_ListOfPnt& aLP)
744 // try to fill it yourself
745 Standard_Boolean bInf1, bInf2;
746 Standard_Integer j, aNbT;
747 Standard_Real dT, aT, aT1, aT2;
749 Handle(Geom_Curve) aC3D;
751 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
756 bInf1=Precision::IsNegativeInfinite(aT1);
757 bInf2=Precision::IsPositiveInfinite(aT2);
758 if (bInf1 || bInf2) {
764 for (j=1; j<=aNbPntsMin; ++j) {
771 //=======================================================================
772 //function : CheckData
774 //=======================================================================
775 void GEOMAlgo_FinderShapeOn1::CheckData()
779 if(mySurface.IsNull()) {
780 myErrorStatus=10; // mySurface=NULL
784 if (myShape.IsNull()) {
785 myErrorStatus=11; // myShape=NULL
789 if (!(myShapeType==TopAbs_VERTEX ||
790 myShapeType==TopAbs_EDGE ||
791 myShapeType==TopAbs_FACE ||
792 myShapeType==TopAbs_SOLID)) {
793 myErrorStatus=12; // unallowed subshape type
797 if (myState==GEOMAlgo_ST_UNKNOWN ||
798 myState==GEOMAlgo_ST_INOUT) {
799 myErrorStatus=13; // unallowed state type
803 GeomAbs_SurfaceType aType;
805 myGAS.Load(mySurface);
806 aType=myGAS.GetType();
807 if (!(aType==GeomAbs_Plane ||
808 aType==GeomAbs_Cylinder ||
809 aType==GeomAbs_Sphere)) {
810 myErrorStatus=14; // unallowed surface type
814 //=======================================================================
815 //function : GetPointState
817 //=======================================================================
819 TopAbs_State GEOMAlgo_FinderShapeOn1::GetPointState(const gp_Pnt& aP)
822 GEOMAlgo_SurfaceTools::GetState(aP, myGAS, myTolerance, aSt);
830 // 10 -mySurface=NULL
832 // 12 -unallowed type of subshapes
833 // 13 -unallowed state
834 // 14 -unallowed surface type
835 // 15 -unallowed surface type
836 // 20- no triangulation found
837 // 30- can not obtain the line from the link
842 #include <OSD_Chronometer.hxx>
843 #include <Standard_Static.hxx>
845 Standard_STATIC(OSD_Chronometer, x_S_Chrono);
846 static void x_StartChrono();
847 static void x_StopChrono();
848 static Standard_Boolean x_IsToShow();
850 //=======================================================================
851 //function : x_StartChrono
853 //=======================================================================
857 x_S_Chrono().Reset();
858 x_S_Chrono().Start();
861 //=======================================================================
862 //function : x_StopChrono
864 //=======================================================================
868 Standard_Real Chrono;
870 x_S_Chrono().Show(Chrono);
871 printf(" Tps: %lf\n", Chrono);
872 //cout << "Tps: " << Chrono << endl;
875 //=======================================================================
876 //function : x_IsToShow
878 //=======================================================================
879 Standard_Boolean x_IsToShow()
881 Standard_Boolean bFlag=Standard_False;
883 char *xr=getenv ("STDCHRONO");
885 if (!strcmp (xr, "yes")) {