1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: GEOMAlgo_FinderShapeOn1.cxx
21 // Created: Fri Mar 4 10:31:06 2005
22 // Author: Peter KURNEV
26 #include <GEOMAlgo_FinderShapeOn1.ixx>
30 #include <Precision.hxx>
31 #include <TColStd_Array1OfInteger.hxx>
32 #include <TColStd_MapOfInteger.hxx>
34 #include <gp_Trsf.hxx>
35 #include <gp_Cylinder.hxx>
38 #include <TColgp_Array1OfPnt.hxx>
40 #include <Poly_Array1OfTriangle.hxx>
41 #include <Poly_Triangle.hxx>
42 #include <Poly_PolygonOnTriangulation.hxx>
43 #include <Poly_Triangulation.hxx>
44 #include <Poly_Polygon3D.hxx>
46 #include <Geom_Curve.hxx>
47 #include <Geom_Surface.hxx>
48 #include <GeomAdaptor_Surface.hxx>
49 #include <GeomAbs_SurfaceType.hxx>
50 #include <GeomAdaptor_Curve.hxx>
51 #include <GeomAbs_CurveType.hxx>
53 #include <TopAbs_State.hxx>
55 #include <TopLoc_Location.hxx>
57 #include <TopoDS_Shape.hxx>
58 #include <TopoDS_Vertex.hxx>
59 #include <TopoDS_Face.hxx>
60 #include <TopoDS_Edge.hxx>
63 #include <TopExp_Explorer.hxx>
65 #include <TopTools_IndexedMapOfShape.hxx>
67 #include <BRep_Tool.hxx>
68 #include <BRepLib_MakeEdge.hxx>
70 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
72 #include <GEOMAlgo_SurfaceTools.hxx>
73 #include <GEOMAlgo_StateCollector.hxx>
75 #include <GEOMAlgo_PassKey.hxx>
76 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
77 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
79 //=======================================================================
80 //function : GEOMAlgo_FinderShapeOn1
82 //=======================================================================
83 GEOMAlgo_FinderShapeOn1::GEOMAlgo_FinderShapeOn1()
88 myShapeType=TopAbs_VERTEX;
89 myState=GEOMAlgo_ST_UNKNOWN;
93 //=======================================================================
96 //=======================================================================
97 GEOMAlgo_FinderShapeOn1::~GEOMAlgo_FinderShapeOn1()
100 //=======================================================================
101 //function : SetSurface
103 //=======================================================================
104 void GEOMAlgo_FinderShapeOn1::SetSurface(const Handle(Geom_Surface)& aS)
108 //=======================================================================
111 //=======================================================================
112 const Handle(Geom_Surface)& GEOMAlgo_FinderShapeOn1::Surface() const
116 //=======================================================================
117 //function : SetShapeType
119 //=======================================================================
120 void GEOMAlgo_FinderShapeOn1::SetShapeType(const TopAbs_ShapeEnum aType)
124 //=======================================================================
125 //function : ShapeType
127 //=======================================================================
128 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn1::ShapeType()const
132 //=======================================================================
133 //function : SetState
135 //=======================================================================
136 void GEOMAlgo_FinderShapeOn1::SetState(const GEOMAlgo_State aState)
140 //=======================================================================
143 //=======================================================================
144 GEOMAlgo_State GEOMAlgo_FinderShapeOn1::State() const
148 //=======================================================================
149 //function : SetNbPntsMin
151 //=======================================================================
152 void GEOMAlgo_FinderShapeOn1::SetNbPntsMin(const Standard_Integer aNb)
156 //=======================================================================
157 //function : NbPntsMin
159 //=======================================================================
160 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMin()const
164 //=======================================================================
165 //function : SetNbPntsMax
167 //=======================================================================
168 void GEOMAlgo_FinderShapeOn1::SetNbPntsMax(const Standard_Integer aNb)
172 //=======================================================================
173 //function : NbPntsMax
175 //=======================================================================
176 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMax()const
180 //=======================================================================
183 //=======================================================================
184 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn1::MSS() const
188 //=======================================================================
191 //=======================================================================
192 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn1::Shapes() const
194 Standard_Integer i, aNb;
195 TopTools_ListOfShape* pL;
197 pL=(TopTools_ListOfShape*) &myLS;
201 for (i=1; i<=aNb; ++i) {
202 const TopoDS_Shape& aS=myMSS.FindKey(i);
203 if (aS.ShapeType()==myShapeType) {
209 //=======================================================================
212 //=======================================================================
213 void GEOMAlgo_FinderShapeOn1::Perform()
230 if (myShapeType==TopAbs_VERTEX) {
239 if (myShapeType==TopAbs_EDGE) {
248 if (myShapeType==TopAbs_FACE) {
256 //=======================================================================
257 //function : ProcessVertices
259 //=======================================================================
260 void GEOMAlgo_FinderShapeOn1::ProcessVertices()
264 Standard_Boolean bIsConformState;
265 Standard_Integer i, aNb;
267 TopTools_IndexedMapOfShape aM;
270 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
272 for (i=1; i<=aNb; ++i) {
273 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
274 aP=BRep_Tool::Pnt(aV);
276 aSt = GetPointState( aP );
277 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
279 if (myShapeType==TopAbs_VERTEX){
280 if (bIsConformState) {
284 else if (bIsConformState || aSt==TopAbs_ON) {
289 //=======================================================================
290 //function : ProcessEdges
292 //=======================================================================
293 void GEOMAlgo_FinderShapeOn1::ProcessEdges()
297 Standard_Boolean bIsConformState, bIsToBreak;
298 Standard_Integer i, aNb, iCnt;
300 TopTools_IndexedMapOfShape aM;
301 TopExp_Explorer aExp;
302 GEOMAlgo_ListIteratorOfListOfPnt aIt;
303 GeomAbs_SurfaceType aType1;
305 aType1=myGAS.GetType();
307 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
309 for (i=1; i<=aNb; ++i) {
310 GEOMAlgo_ListOfPnt aLP;
311 GEOMAlgo_StateCollector aSC;
313 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
315 aExp.Init(aE, TopAbs_VERTEX);
316 for (; aExp.More(); aExp.Next()) {
317 const TopoDS_Shape& aV=aExp.Current();
319 bIsConformState=myMSS.Contains(aV);
320 if (!bIsConformState) {
321 break;// vertex has non-conformed state
324 aSt=myMSS.FindFromKey(aV);
325 aSC.AppendState(aSt);
329 if (!bIsConformState) {
330 continue; // vertex has non-conformed state,skip edge
333 if (BRep_Tool::Degenerated(aE)) {
338 if (myState==GEOMAlgo_ST_ON && aType1==GeomAbs_Sphere) {
339 Standard_Real aT1, aT2;
340 Handle(Geom_Curve) aC;
341 GeomAdaptor_Curve aGAC;
342 GeomAbs_CurveType aType2;
344 aC=BRep_Tool::Curve(aE, aT1, aT2);
347 aType2=aGAC.GetType();
348 if (aType2==GeomAbs_Line) {
353 InnerPoints(aE, aLP);
358 bIsConformState=Standard_True;
360 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
362 if (iCnt > myNbPntsMax) {
367 const gp_Pnt& aP=aIt.Value();
368 aSt = GetPointState( aP );
369 bIsToBreak=aSC.AppendState(aSt);
377 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
378 if (myShapeType==TopAbs_EDGE) {
379 if (bIsConformState) {
383 else if (bIsConformState || aSt==TopAbs_ON) {
386 } // for (i=1; i<=aNb; ++i) next edge
388 //=======================================================================
389 //function : ProcessFaces
391 //=======================================================================
392 void GEOMAlgo_FinderShapeOn1::ProcessFaces()
396 Standard_Boolean bIsConformState, bIsToBreak;
397 Standard_Integer i, aNbF, iCnt;
399 TopTools_IndexedMapOfShape aM;
400 TopExp_Explorer aExp;
401 GEOMAlgo_ListIteratorOfListOfPnt aIt;
402 GeomAbs_SurfaceType aType1, aType2;
404 aType1=myGAS.GetType();
406 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
408 for (i=1; i<=aNbF; ++i) {
409 GEOMAlgo_StateCollector aSC;
410 GEOMAlgo_ListOfPnt aLP;
412 const TopoDS_Face& aF=TopoDS::Face(aM(i));
414 if (myState==GEOMAlgo_ST_ON) {
415 Handle(Geom_Surface) aS;
416 GeomAdaptor_Surface aGAS;
418 aS=BRep_Tool::Surface(aF);
420 aType2=aGAS.GetType();
421 if (aType2!=aType1) {
426 aExp.Init(aF, TopAbs_EDGE);
427 for (; aExp.More(); aExp.Next()) {
428 const TopoDS_Shape& aE=aExp.Current();
429 bIsConformState=myMSS.Contains(aE);
430 if (!bIsConformState) {
431 break;// edge has non-conformed state
434 aSt=myMSS.FindFromKey(aE);
435 aSC.AppendState(aSt);
439 if (!bIsConformState) {
440 continue; // edge has non-conformed state,skip face
443 InnerPoints(aF, aLP);
448 bIsConformState=Standard_True;
450 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
452 if (iCnt > myNbPntsMax) {
457 const gp_Pnt& aP=aIt.Value();
458 aSt = GetPointState( aP );
459 bIsToBreak=aSC.AppendState(aSt);
467 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
468 if (myShapeType==TopAbs_FACE) {
469 if (bIsConformState) {
473 else if (bIsConformState || aSt==TopAbs_ON) {
476 }// for (i=1; i<=aNb; ++i) next face
478 //=======================================================================
479 //function : ProcessSolids
481 //=======================================================================
482 void GEOMAlgo_FinderShapeOn1::ProcessSolids()
486 Standard_Boolean bIsConformState;
487 Standard_Integer i, aNbS, j, aNbF;
488 TopTools_IndexedMapOfShape aM, aMF;
491 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
493 for (i=1; i<=aNbS; ++i) {
494 GEOMAlgo_StateCollector aSC;
496 const TopoDS_Shape& aSd=aM(i);
498 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
500 for (j=1; j<=aNbF; ++j) {
501 const TopoDS_Shape& aF=aMF(j);
502 bIsConformState=myMSS.Contains(aF);
503 if (!bIsConformState) {
504 break;// face has non-conformed state
507 aSt=myMSS.FindFromKey(aF);
508 aSC.AppendState(aSt);
512 if (!bIsConformState) {
513 continue; // face has non-conformed state,skip solid
518 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
519 if (bIsConformState) {
525 //=======================================================================
526 //function : InnerPoints
528 //=======================================================================
529 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Face& aF,
530 GEOMAlgo_ListOfPnt& aLP)
534 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
535 TopLoc_Location aLoc;
536 Handle(Poly_Triangulation) aTRF;
537 TColStd_MapOfInteger aMBN;
538 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
539 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
544 aTRF=BRep_Tool::Triangulation(aF, aLoc);
546 myErrorStatus=20; // no triangulation found
550 const gp_Trsf& aTrsf=aLoc.Transformation();
551 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
552 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
554 // map link/nbtriangles
557 for (j=j1; j<=j2; ++j) {
558 const Poly_Triangle& aTr=aTrs(j);
559 aTr.Get(n[0], n[1], n[2]);
561 for (k=0; k<3; ++k) {
562 GEOMAlgo_PassKey aPK;
564 aPK.SetIds(n[k], n[k+1]);
565 if (aMPKI.IsBound(aPK)) {
566 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
575 // boundary nodes aMBN
576 aNbLinks=aMPKI.Extent();
577 aIt.Initialize(aMPKI);
578 for (; aIt.More(); aIt.Next()) {
581 const GEOMAlgo_PassKey& aPK=aIt.Key();
585 pIds=(Standard_Integer*)aPK.Key();
586 for (k=1; k<3; ++k) {
587 aNx=*(pIds+aNbMax-k);
591 aNx=(Standard_Integer)aPK.Id(1);
593 aNx=(Standard_Integer)aPK.Id(2);
599 // inner nodes=all_nodes - boundary_nodes
602 for (j=j1; j<=j2; ++j) {
603 if (!aMBN.Contains(j)) {
604 aP=aNodes(j).Transformed(aTrsf);
611 if (!aNb && myNbPntsMin) {
612 // try to fill it yourself
613 Standard_Boolean bIsDone;
614 Standard_Integer aN1, aN2;
615 Handle(Geom_Surface) aS;
616 GeomAdaptor_Surface aGAS;
617 GeomAbs_SurfaceType aType;
619 aS=BRep_Tool::Surface(aF);
621 aType=aGAS.GetType();
622 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
624 aNbLinks=aMPKI.Extent();
625 aIt.Initialize(aMPKI);
626 for (; aIt.More(); aIt.Next()) {
629 // take the first having occured inner link
631 const GEOMAlgo_PassKey& aPK=aIt.Key();
635 pIds=(Standard_Integer*)aPK.Key();
636 aN1=*(pIds+aNbMax-1);
637 aN2=*(pIds+aNbMax-2);
640 aN1=(Standard_Integer)aPK.Id(1);
641 aN2=(Standard_Integer)aPK.Id(2);
643 aP1=aNodes(aN1).Transformed(aTrsf);
644 aP2=aNodes(aN2).Transformed(aTrsf);
646 if (aType==GeomAbs_Cylinder) {
647 Standard_Real aTolSM;
650 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
651 aCyl=aGAS.Cylinder();
652 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
657 BRepLib_MakeEdge aBME(aP1, aP2);
658 bIsDone=aBME.IsDone();
660 myErrorStatus=30; //can not obtain the line fron the link
664 const TopoDS_Shape& aSx=aBME.Shape();
665 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
667 InnerPoints(aE, myNbPntsMin, aLP);
670 }// for (; aIt.More(); aIt.Next())
671 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
672 }// if (!aNb && myNbPntsMin) {
674 //=======================================================================
675 //function : InnerPoints
677 //=======================================================================
678 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
679 GEOMAlgo_ListOfPnt& aLP)
683 Standard_Integer j, aNbNodes, aIndex, aNb;
684 Handle(Poly_PolygonOnTriangulation) aPTE;
685 Handle(Poly_Triangulation) aTRE;
686 TopLoc_Location aLoc;
690 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
691 if (aTRE.IsNull() || aPTE.IsNull()) {
692 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
694 myErrorStatus=20; // no triangulation found
697 const gp_Trsf& aTrsf=aLoc.Transformation();
698 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
700 aNbNodes=aPE->NbNodes();
701 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
702 for (j=low+1; j<up; ++j) {
703 aP=aNodes(j).Transformed(aTrsf);
708 const gp_Trsf& aTrsf=aLoc.Transformation();
709 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
711 aNbNodes=aPTE->NbNodes();
712 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
713 for (j=2; j<aNbNodes; ++j) {
715 aP=aNodes(aIndex).Transformed(aTrsf);
721 if (!aNb && myNbPntsMin) {
722 // try to fill it yourself
723 InnerPoints(aE, myNbPntsMin, aLP);
727 //=======================================================================
728 //function : InnerPoints
730 //=======================================================================
731 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
732 const Standard_Integer aNbPntsMin,
733 GEOMAlgo_ListOfPnt& aLP)
735 // try to fill it yourself
736 Standard_Boolean bInf1, bInf2;
737 Standard_Integer j, aNbT;
738 Standard_Real dT, aT, aT1, aT2;
740 Handle(Geom_Curve) aC3D;
742 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
747 bInf1=Precision::IsNegativeInfinite(aT1);
748 bInf2=Precision::IsPositiveInfinite(aT2);
749 if (bInf1 || bInf2) {
755 for (j=1; j<=aNbPntsMin; ++j) {
762 //=======================================================================
763 //function : CheckData
765 //=======================================================================
766 void GEOMAlgo_FinderShapeOn1::CheckData()
770 if(mySurface.IsNull()) {
771 myErrorStatus=10; // mySurface=NULL
775 if (myShape.IsNull()) {
776 myErrorStatus=11; // myShape=NULL
780 if (!(myShapeType==TopAbs_VERTEX ||
781 myShapeType==TopAbs_EDGE ||
782 myShapeType==TopAbs_FACE ||
783 myShapeType==TopAbs_SOLID)) {
784 myErrorStatus=12; // unallowed subshape type
788 if (myState==GEOMAlgo_ST_UNKNOWN ||
789 myState==GEOMAlgo_ST_INOUT) {
790 myErrorStatus=13; // unallowed state type
794 GeomAbs_SurfaceType aType;
796 myGAS.Load(mySurface);
797 aType=myGAS.GetType();
798 if (!(aType==GeomAbs_Plane ||
799 aType==GeomAbs_Cylinder ||
800 aType==GeomAbs_Sphere)) {
801 myErrorStatus=14; // unallowed surface type
805 //=======================================================================
806 //function : GetPointState
808 //=======================================================================
810 TopAbs_State GEOMAlgo_FinderShapeOn1::GetPointState(const gp_Pnt& aP)
813 GEOMAlgo_SurfaceTools::GetState(aP, myGAS, myTolerance, aSt);
821 // 10 -mySurface=NULL
823 // 12 -unallowed type of subshapes
824 // 13 -unallowed state
825 // 14 -unallowed surface type
826 // 15 -unallowed surface type
827 // 20- no triangulation found
828 // 30- can not obtain the line from the link
833 #include <OSD_Chronometer.hxx>
834 #include <Standard_Static.hxx>
836 Standard_STATIC(OSD_Chronometer, x_S_Chrono);
837 static void x_StartChrono();
838 static void x_StopChrono();
839 static Standard_Boolean x_IsToShow();
841 //=======================================================================
842 //function : x_StartChrono
844 //=======================================================================
848 x_S_Chrono().Reset();
849 x_S_Chrono().Start();
852 //=======================================================================
853 //function : x_StopChrono
855 //=======================================================================
859 Standard_Real Chrono;
861 x_S_Chrono().Show(Chrono);
862 printf(" Tps: %lf\n", Chrono);
863 //cout << "Tps: " << Chrono << endl;
866 //=======================================================================
867 //function : x_IsToShow
869 //=======================================================================
870 Standard_Boolean x_IsToShow()
872 Standard_Boolean bFlag=Standard_False;
874 char *xr=getenv ("STDCHRONO");
876 if (!strcmp (xr, "yes")) {