1 // Copyright (C) 2007-2011 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
22 // File: GEOMAlgo_FinderShapeOn1.cxx
23 // Created: Fri Mar 4 10:31:06 2005
24 // Author: Peter KURNEV
26 #include <GEOMAlgo_FinderShapeOn2.ixx>
28 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
30 #include <GEOMAlgo_SurfaceTools.hxx>
31 #include <GEOMAlgo_StateCollector.hxx>
32 #include <GEOMAlgo_FinderShapeOn.hxx>
34 #include <GEOMAlgo_PassKey.hxx>
35 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
36 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
38 #include <Basics_OCCTVersion.hxx>
42 #include <Precision.hxx>
43 #include <TColStd_Array1OfInteger.hxx>
44 #include <TColStd_MapOfInteger.hxx>
46 #include <gp_Trsf.hxx>
47 #include <gp_Cylinder.hxx>
50 #include <TColgp_Array1OfPnt.hxx>
52 #include <Poly_Array1OfTriangle.hxx>
53 #include <Poly_Triangle.hxx>
54 #include <Poly_PolygonOnTriangulation.hxx>
55 #include <Poly_Triangulation.hxx>
56 #include <Poly_Polygon3D.hxx>
58 #include <Geom_Curve.hxx>
59 #include <Geom_Surface.hxx>
60 #include <GeomAdaptor_Surface.hxx>
61 #include <GeomAbs_SurfaceType.hxx>
62 #include <GeomAdaptor_Curve.hxx>
63 #include <GeomAbs_CurveType.hxx>
65 #include <TopAbs_State.hxx>
67 #include <TopLoc_Location.hxx>
69 #include <TopoDS_Shape.hxx>
70 #include <TopoDS_Vertex.hxx>
71 #include <TopoDS_Face.hxx>
72 #include <TopoDS_Edge.hxx>
75 #include <TopExp_Explorer.hxx>
77 #include <TopTools_IndexedMapOfShape.hxx>
79 #include <BRep_Tool.hxx>
80 #include <BRepLib_MakeEdge.hxx>
82 //=======================================================================
83 //function : GEOMAlgo_FinderShapeOn1
85 //=======================================================================
86 GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
91 myShapeType=TopAbs_VERTEX;
92 myState=GEOMAlgo_ST_UNKNOWN;
96 //=======================================================================
99 //=======================================================================
100 GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
103 //=======================================================================
106 //=======================================================================
107 void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
111 //=======================================================================
114 //=======================================================================
115 const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
119 //=======================================================================
120 //function : SetShapeType
122 //=======================================================================
123 void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
127 //=======================================================================
128 //function : ShapeType
130 //=======================================================================
131 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
135 //=======================================================================
136 //function : SetState
138 //=======================================================================
139 void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
143 //=======================================================================
146 //=======================================================================
147 GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
151 //=======================================================================
152 //function : SetNbPntsMin
154 //=======================================================================
155 void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
159 //=======================================================================
160 //function : NbPntsMin
162 //=======================================================================
163 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
167 //=======================================================================
168 //function : SetNbPntsMax
170 //=======================================================================
171 void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
175 //=======================================================================
176 //function : NbPntsMax
178 //=======================================================================
179 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
183 //=======================================================================
186 //=======================================================================
187 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
191 //=======================================================================
194 //=======================================================================
195 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::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_FinderShapeOn2::Perform()
228 #if OCC_VERSION_LARGE > 0x06050200
229 // Initialize the context
230 GEOMAlgo_ShapeAlgo::Perform();
233 myClsf->SetTolerance(myTolerance);
240 if (myShapeType==TopAbs_VERTEX) {
249 if (myShapeType==TopAbs_EDGE) {
258 if (myShapeType==TopAbs_FACE) {
266 //=======================================================================
267 //function : CheckData
269 //=======================================================================
270 void GEOMAlgo_FinderShapeOn2::CheckData()
272 Standard_Integer iErr;
276 if(myClsf.IsNull()) {
277 myErrorStatus=10; // myClsf=NULL
282 iErr=myClsf->ErrorStatus();
284 myErrorStatus=41; // invalid data for classifier
288 if (myShape.IsNull()) {
289 myErrorStatus=11; // myShape=NULL
293 if (!(myShapeType==TopAbs_VERTEX ||
294 myShapeType==TopAbs_EDGE ||
295 myShapeType==TopAbs_FACE ||
296 myShapeType==TopAbs_SOLID)) {
297 myErrorStatus=12; // unallowed sub-shape type
301 if (myState==GEOMAlgo_ST_UNKNOWN ||
302 myState==GEOMAlgo_ST_INOUT) {
303 myErrorStatus=13; // unallowed state type
307 //=======================================================================
308 //function : ProcessVertices
310 //=======================================================================
311 void GEOMAlgo_FinderShapeOn2::ProcessVertices()
315 Standard_Boolean bIsConformState;
316 Standard_Integer i, aNb, iErr;
318 TopTools_IndexedMapOfShape aM;
321 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
323 for (i=1; i<=aNb; ++i) {
324 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
325 aP=BRep_Tool::Pnt(aV);
329 iErr=myClsf->ErrorStatus();
331 myErrorStatus=40; // point can not be classified
336 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
338 if (myShapeType==TopAbs_VERTEX){
339 if (bIsConformState) {
343 else if (bIsConformState || aSt==TopAbs_ON) {
348 //=======================================================================
349 //function : ProcessEdges
351 //=======================================================================
352 void GEOMAlgo_FinderShapeOn2::ProcessEdges()
356 Standard_Boolean bIsConformState, bIsToBreak;
357 Standard_Integer i, aNb, iCnt, iErr;
359 TopTools_IndexedMapOfShape aM;
360 TopExp_Explorer aExp;
361 GEOMAlgo_ListIteratorOfListOfPnt aIt;
363 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
365 for (i=1; i<=aNb; ++i) {
366 GEOMAlgo_ListOfPnt aLP;
367 GEOMAlgo_StateCollector aSC;
369 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
371 aExp.Init(aE, TopAbs_VERTEX);
372 for (; aExp.More(); aExp.Next()) {
373 const TopoDS_Shape& aV=aExp.Current();
375 bIsConformState=myMSS.Contains(aV);
376 if (!bIsConformState) {
377 break;// vertex has non-conformed state
380 aSt=myMSS.FindFromKey(aV);
381 aSC.AppendState(aSt);
385 if (!bIsConformState) {
386 continue; // vertex has non-conformed state,skip edge
389 if (BRep_Tool::Degenerated(aE)) {
394 if (myState==GEOMAlgo_ST_ON) {
395 Standard_Boolean bCanBeON;
396 Standard_Real aT1, aT2;
397 Handle(Geom_Curve) aC;
399 aC=BRep_Tool::Curve(aE, aT1, aT2);
400 bCanBeON=myClsf->CanBeON(aC);
406 InnerPoints(aE, aLP);
411 bIsConformState=Standard_True;
413 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
415 if (iCnt > myNbPntsMax) {
420 const gp_Pnt& aP=aIt.Value();
424 iErr=myClsf->ErrorStatus();
426 myErrorStatus=40; // point can not be classified
432 bIsToBreak=aSC.AppendState(aSt);
440 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
441 if (myShapeType==TopAbs_EDGE) {
442 if (bIsConformState) {
446 else if (bIsConformState || aSt==TopAbs_ON) {
449 } // for (i=1; i<=aNb; ++i) next edge
451 //=======================================================================
452 //function : ProcessFaces
454 //=======================================================================
455 void GEOMAlgo_FinderShapeOn2::ProcessFaces()
459 Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
460 Standard_Integer i, aNbF, iCnt, iErr;
462 TopTools_IndexedMapOfShape aM;
463 TopExp_Explorer aExp;
464 GEOMAlgo_ListIteratorOfListOfPnt aIt;
466 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
468 for (i=1; i<=aNbF; ++i) {
469 GEOMAlgo_StateCollector aSC;
470 GEOMAlgo_ListOfPnt aLP;
472 const TopoDS_Face& aF=TopoDS::Face(aM(i));
474 if (myState==GEOMAlgo_ST_ON) {
475 Handle(Geom_Surface) aS;
477 aS=BRep_Tool::Surface(aF);
478 bCanBeON=myClsf->CanBeON(aS);
484 aExp.Init(aF, TopAbs_EDGE);
485 for (; aExp.More(); aExp.Next()) {
486 const TopoDS_Shape& aE=aExp.Current();
487 bIsConformState=myMSS.Contains(aE);
488 if (!bIsConformState) {
489 break;// edge has non-conformed state
492 aSt=myMSS.FindFromKey(aE);
493 aSC.AppendState(aSt);
497 if (!bIsConformState) {
498 continue; // edge has non-conformed state,skip face
501 InnerPoints(aF, aLP);
506 bIsConformState=Standard_True;
508 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
510 if (iCnt > myNbPntsMax) {
515 const gp_Pnt& aP=aIt.Value();
519 iErr=myClsf->ErrorStatus();
521 myErrorStatus=40; // point can not be classified
527 bIsToBreak=aSC.AppendState(aSt);
535 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
536 if (myShapeType==TopAbs_FACE) {
537 if (bIsConformState) {
541 else if (bIsConformState || aSt==TopAbs_ON) {
544 }// for (i=1; i<=aNb; ++i) next face
546 //=======================================================================
547 //function : ProcessSolids
549 //=======================================================================
550 void GEOMAlgo_FinderShapeOn2::ProcessSolids()
554 Standard_Boolean bIsConformState;
555 Standard_Integer i, aNbS, j, aNbF;
556 TopTools_IndexedMapOfShape aM, aMF;
559 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
561 for (i=1; i<=aNbS; ++i) {
562 GEOMAlgo_StateCollector aSC;
564 const TopoDS_Shape& aSd=aM(i);
566 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
568 for (j=1; j<=aNbF; ++j) {
569 const TopoDS_Shape& aF=aMF(j);
570 bIsConformState=myMSS.Contains(aF);
571 if (!bIsConformState) {
572 break;// face has non-conformed state
575 aSt=myMSS.FindFromKey(aF);
576 aSC.AppendState(aSt);
580 if (!bIsConformState) {
581 continue; // face has non-conformed state,skip solid
586 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
587 if (bIsConformState) {
593 //=======================================================================
594 //function : InnerPoints
596 //=======================================================================
597 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
598 GEOMAlgo_ListOfPnt& aLP)
602 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
603 TopLoc_Location aLoc;
604 Handle(Poly_Triangulation) aTRF;
605 TColStd_MapOfInteger aMBN;
606 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
607 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
612 aTRF=BRep_Tool::Triangulation(aF, aLoc);
614 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
615 myWarningStatus=20; // no triangulation found
618 aTRF=BRep_Tool::Triangulation(aF, aLoc);
621 const gp_Trsf& aTrsf=aLoc.Transformation();
622 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
623 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
625 // map link/nbtriangles
628 for (j=j1; j<=j2; ++j) {
629 const Poly_Triangle& aTr=aTrs(j);
630 aTr.Get(n[0], n[1], n[2]);
632 for (k=0; k<3; ++k) {
633 GEOMAlgo_PassKey aPK;
635 aPK.SetIds(n[k], n[k+1]);
636 if (aMPKI.IsBound(aPK)) {
637 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
646 // boundary nodes aMBN
647 aNbLinks=aMPKI.Extent();
648 aIt.Initialize(aMPKI);
649 for (; aIt.More(); aIt.Next()) {
652 const GEOMAlgo_PassKey& aPK=aIt.Key();
656 pIds=(Standard_Integer*)aPK.Key();
657 for (k=1; k<3; ++k) {
658 aNx=*(pIds+aNbMax-k);
662 aNx=(Standard_Integer)aPK.Id(1);
664 aNx=(Standard_Integer)aPK.Id(2);
670 // inner nodes=all_nodes - boundary_nodes
673 for (j=j1; j<=j2; ++j) {
674 if (!aMBN.Contains(j)) {
675 aP=aNodes(j).Transformed(aTrsf);
682 if (!aNb && myNbPntsMin) {
683 // try to fill it yourself
684 Standard_Boolean bIsDone;
685 Standard_Integer aN1, aN2;
686 Handle(Geom_Surface) aS;
687 GeomAdaptor_Surface aGAS;
688 GeomAbs_SurfaceType aType;
690 aS=BRep_Tool::Surface(aF);
692 aType=aGAS.GetType();
693 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
695 aNbLinks=aMPKI.Extent();
696 aIt.Initialize(aMPKI);
697 for (; aIt.More(); aIt.Next()) {
700 // take the first having occured inner link
702 const GEOMAlgo_PassKey& aPK=aIt.Key();
706 pIds=(Standard_Integer*)aPK.Key();
707 aN1=*(pIds+aNbMax-1);
708 aN2=*(pIds+aNbMax-2);
711 aN1=(Standard_Integer)aPK.Id(1);
712 aN2=(Standard_Integer)aPK.Id(2);
714 aP1=aNodes(aN1).Transformed(aTrsf);
715 aP2=aNodes(aN2).Transformed(aTrsf);
717 if (aType==GeomAbs_Cylinder) {
718 Standard_Real aTolSM;
721 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
722 aCyl=aGAS.Cylinder();
723 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
728 BRepLib_MakeEdge aBME(aP1, aP2);
729 bIsDone=aBME.IsDone();
731 myErrorStatus=30; //can not obtain the line fron the link
735 const TopoDS_Shape& aSx=aBME.Shape();
736 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
738 InnerPoints(aE, myNbPntsMin, aLP);
741 }// for (; aIt.More(); aIt.Next())
742 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
743 }// if (!aNb && myNbPntsMin) {
745 //=======================================================================
746 //function : InnerPoints
748 //=======================================================================
749 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
750 GEOMAlgo_ListOfPnt& aLP)
754 Standard_Integer j, aNbNodes, aIndex, aNb;
755 Handle(Poly_PolygonOnTriangulation) aPTE;
756 Handle(Poly_Triangulation) aTRE;
757 TopLoc_Location aLoc;
761 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
762 if (aTRE.IsNull() || aPTE.IsNull()) {
763 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
765 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
766 myErrorStatus=20; // no triangulation found
769 aPE = BRep_Tool::Polygon3D(aE, aLoc);
771 const gp_Trsf& aTrsf=aLoc.Transformation();
772 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
774 aNbNodes=aPE->NbNodes();
775 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
776 for (j=low+1; j<up; ++j) {
777 aP=aNodes(j).Transformed(aTrsf);
782 const gp_Trsf& aTrsf=aLoc.Transformation();
783 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
785 aNbNodes=aPTE->NbNodes();
786 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
787 for (j=2; j<aNbNodes; ++j) {
789 aP=aNodes(aIndex).Transformed(aTrsf);
795 if (!aNb && myNbPntsMin) {
796 // try to fill it yourself
797 InnerPoints(aE, myNbPntsMin, aLP);
801 //=======================================================================
802 //function : InnerPoints
804 //=======================================================================
805 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
806 const Standard_Integer aNbPntsMin,
807 GEOMAlgo_ListOfPnt& aLP)
809 // try to fill it yourself
810 Standard_Boolean bInf1, bInf2;
811 Standard_Integer j, aNbT;
812 Standard_Real dT, aT, aT1, aT2;
814 Handle(Geom_Curve) aC3D;
816 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
821 bInf1=Precision::IsNegativeInfinite(aT1);
822 bInf2=Precision::IsPositiveInfinite(aT2);
823 if (bInf1 || bInf2) {
829 for (j=1; j<=aNbPntsMin; ++j) {
841 // 12 -unallowed type of sub-shapes
842 // 13 -unallowed state
843 // 15 -unallowed surface type
844 // 20- no triangulation found
845 // 30- can not obtain the line from the link
846 // 40- point can not be classified
847 // 41- invalid data for classifier