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_FinderShapeOn2.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>
74 #include <GEOMAlgo_FinderShapeOn.hxx>
76 #include <GEOMAlgo_PassKey.hxx>
77 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
78 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
80 //=======================================================================
81 //function : GEOMAlgo_FinderShapeOn1
83 //=======================================================================
84 GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
89 myShapeType=TopAbs_VERTEX;
90 myState=GEOMAlgo_ST_UNKNOWN;
94 //=======================================================================
97 //=======================================================================
98 GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
101 //=======================================================================
104 //=======================================================================
105 void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
109 //=======================================================================
112 //=======================================================================
113 const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
117 //=======================================================================
118 //function : SetShapeType
120 //=======================================================================
121 void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
125 //=======================================================================
126 //function : ShapeType
128 //=======================================================================
129 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
133 //=======================================================================
134 //function : SetState
136 //=======================================================================
137 void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
141 //=======================================================================
144 //=======================================================================
145 GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
149 //=======================================================================
150 //function : SetNbPntsMin
152 //=======================================================================
153 void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
157 //=======================================================================
158 //function : NbPntsMin
160 //=======================================================================
161 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
165 //=======================================================================
166 //function : SetNbPntsMax
168 //=======================================================================
169 void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
173 //=======================================================================
174 //function : NbPntsMax
176 //=======================================================================
177 Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
181 //=======================================================================
184 //=======================================================================
185 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
189 //=======================================================================
192 //=======================================================================
193 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::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_FinderShapeOn2::Perform()
226 myClsf->SetTolerance(myTolerance);
233 if (myShapeType==TopAbs_VERTEX) {
242 if (myShapeType==TopAbs_EDGE) {
251 if (myShapeType==TopAbs_FACE) {
259 //=======================================================================
260 //function : CheckData
262 //=======================================================================
263 void GEOMAlgo_FinderShapeOn2::CheckData()
265 Standard_Integer iErr;
269 if(myClsf.IsNull()) {
270 myErrorStatus=10; // myClsf=NULL
275 iErr=myClsf->ErrorStatus();
277 myErrorStatus=41; // invalid data for classifier
281 if (myShape.IsNull()) {
282 myErrorStatus=11; // myShape=NULL
286 if (!(myShapeType==TopAbs_VERTEX ||
287 myShapeType==TopAbs_EDGE ||
288 myShapeType==TopAbs_FACE ||
289 myShapeType==TopAbs_SOLID)) {
290 myErrorStatus=12; // unallowed subshape type
294 if (myState==GEOMAlgo_ST_UNKNOWN ||
295 myState==GEOMAlgo_ST_INOUT) {
296 myErrorStatus=13; // unallowed state type
300 //=======================================================================
301 //function : ProcessVertices
303 //=======================================================================
304 void GEOMAlgo_FinderShapeOn2::ProcessVertices()
308 Standard_Boolean bIsConformState;
309 Standard_Integer i, aNb, iErr;
311 TopTools_IndexedMapOfShape aM;
314 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
316 for (i=1; i<=aNb; ++i) {
317 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
318 aP=BRep_Tool::Pnt(aV);
322 iErr=myClsf->ErrorStatus();
324 myErrorStatus=40; // point can not be classified
329 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
331 if (myShapeType==TopAbs_VERTEX){
332 if (bIsConformState) {
336 else if (bIsConformState || aSt==TopAbs_ON) {
341 //=======================================================================
342 //function : ProcessEdges
344 //=======================================================================
345 void GEOMAlgo_FinderShapeOn2::ProcessEdges()
349 Standard_Boolean bIsConformState, bIsToBreak;
350 Standard_Integer i, aNb, iCnt, iErr;
352 TopTools_IndexedMapOfShape aM;
353 TopExp_Explorer aExp;
354 GEOMAlgo_ListIteratorOfListOfPnt aIt;
356 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
358 for (i=1; i<=aNb; ++i) {
359 GEOMAlgo_ListOfPnt aLP;
360 GEOMAlgo_StateCollector aSC;
362 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
364 aExp.Init(aE, TopAbs_VERTEX);
365 for (; aExp.More(); aExp.Next()) {
366 const TopoDS_Shape& aV=aExp.Current();
368 bIsConformState=myMSS.Contains(aV);
369 if (!bIsConformState) {
370 break;// vertex has non-conformed state
373 aSt=myMSS.FindFromKey(aV);
374 aSC.AppendState(aSt);
378 if (!bIsConformState) {
379 continue; // vertex has non-conformed state,skip edge
382 if (BRep_Tool::Degenerated(aE)) {
387 if (myState==GEOMAlgo_ST_ON) {
388 Standard_Boolean bCanBeON;
389 Standard_Real aT1, aT2;
390 Handle(Geom_Curve) aC;
392 aC=BRep_Tool::Curve(aE, aT1, aT2);
393 bCanBeON=myClsf->CanBeON(aC);
399 InnerPoints(aE, aLP);
404 bIsConformState=Standard_True;
406 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
408 if (iCnt > myNbPntsMax) {
413 const gp_Pnt& aP=aIt.Value();
417 iErr=myClsf->ErrorStatus();
419 myErrorStatus=40; // point can not be classified
425 bIsToBreak=aSC.AppendState(aSt);
433 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
434 if (myShapeType==TopAbs_EDGE) {
435 if (bIsConformState) {
439 else if (bIsConformState || aSt==TopAbs_ON) {
442 } // for (i=1; i<=aNb; ++i) next edge
444 //=======================================================================
445 //function : ProcessFaces
447 //=======================================================================
448 void GEOMAlgo_FinderShapeOn2::ProcessFaces()
452 Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
453 Standard_Integer i, aNbF, iCnt, iErr;
455 TopTools_IndexedMapOfShape aM;
456 TopExp_Explorer aExp;
457 GEOMAlgo_ListIteratorOfListOfPnt aIt;
459 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
461 for (i=1; i<=aNbF; ++i) {
462 GEOMAlgo_StateCollector aSC;
463 GEOMAlgo_ListOfPnt aLP;
465 const TopoDS_Face& aF=TopoDS::Face(aM(i));
467 if (myState==GEOMAlgo_ST_ON) {
468 Handle(Geom_Surface) aS;
470 aS=BRep_Tool::Surface(aF);
471 bCanBeON=myClsf->CanBeON(aS);
477 aExp.Init(aF, TopAbs_EDGE);
478 for (; aExp.More(); aExp.Next()) {
479 const TopoDS_Shape& aE=aExp.Current();
480 bIsConformState=myMSS.Contains(aE);
481 if (!bIsConformState) {
482 break;// edge has non-conformed state
485 aSt=myMSS.FindFromKey(aE);
486 aSC.AppendState(aSt);
490 if (!bIsConformState) {
491 continue; // edge has non-conformed state,skip face
494 InnerPoints(aF, aLP);
499 bIsConformState=Standard_True;
501 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
503 if (iCnt > myNbPntsMax) {
508 const gp_Pnt& aP=aIt.Value();
512 iErr=myClsf->ErrorStatus();
514 myErrorStatus=40; // point can not be classified
520 bIsToBreak=aSC.AppendState(aSt);
528 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
529 if (myShapeType==TopAbs_FACE) {
530 if (bIsConformState) {
534 else if (bIsConformState || aSt==TopAbs_ON) {
537 }// for (i=1; i<=aNb; ++i) next face
539 //=======================================================================
540 //function : ProcessSolids
542 //=======================================================================
543 void GEOMAlgo_FinderShapeOn2::ProcessSolids()
547 Standard_Boolean bIsConformState;
548 Standard_Integer i, aNbS, j, aNbF;
549 TopTools_IndexedMapOfShape aM, aMF;
552 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
554 for (i=1; i<=aNbS; ++i) {
555 GEOMAlgo_StateCollector aSC;
557 const TopoDS_Shape& aSd=aM(i);
559 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
561 for (j=1; j<=aNbF; ++j) {
562 const TopoDS_Shape& aF=aMF(j);
563 bIsConformState=myMSS.Contains(aF);
564 if (!bIsConformState) {
565 break;// face has non-conformed state
568 aSt=myMSS.FindFromKey(aF);
569 aSC.AppendState(aSt);
573 if (!bIsConformState) {
574 continue; // face has non-conformed state,skip solid
579 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
580 if (bIsConformState) {
586 //=======================================================================
587 //function : InnerPoints
589 //=======================================================================
590 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
591 GEOMAlgo_ListOfPnt& aLP)
595 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
596 TopLoc_Location aLoc;
597 Handle(Poly_Triangulation) aTRF;
598 TColStd_MapOfInteger aMBN;
599 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
600 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
605 aTRF=BRep_Tool::Triangulation(aF, aLoc);
607 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
608 myWarningStatus=20; // no triangulation found
611 aTRF=BRep_Tool::Triangulation(aF, aLoc);
614 const gp_Trsf& aTrsf=aLoc.Transformation();
615 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
616 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
618 // map link/nbtriangles
621 for (j=j1; j<=j2; ++j) {
622 const Poly_Triangle& aTr=aTrs(j);
623 aTr.Get(n[0], n[1], n[2]);
625 for (k=0; k<3; ++k) {
626 GEOMAlgo_PassKey aPK;
628 aPK.SetIds(n[k], n[k+1]);
629 if (aMPKI.IsBound(aPK)) {
630 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
639 // boundary nodes aMBN
640 aNbLinks=aMPKI.Extent();
641 aIt.Initialize(aMPKI);
642 for (; aIt.More(); aIt.Next()) {
645 const GEOMAlgo_PassKey& aPK=aIt.Key();
649 pIds=(Standard_Integer*)aPK.Key();
650 for (k=1; k<3; ++k) {
651 aNx=*(pIds+aNbMax-k);
655 aNx=(Standard_Integer)aPK.Id(1);
657 aNx=(Standard_Integer)aPK.Id(2);
663 // inner nodes=all_nodes - boundary_nodes
666 for (j=j1; j<=j2; ++j) {
667 if (!aMBN.Contains(j)) {
668 aP=aNodes(j).Transformed(aTrsf);
675 if (!aNb && myNbPntsMin) {
676 // try to fill it yourself
677 Standard_Boolean bIsDone;
678 Standard_Integer aN1, aN2;
679 Handle(Geom_Surface) aS;
680 GeomAdaptor_Surface aGAS;
681 GeomAbs_SurfaceType aType;
683 aS=BRep_Tool::Surface(aF);
685 aType=aGAS.GetType();
686 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
688 aNbLinks=aMPKI.Extent();
689 aIt.Initialize(aMPKI);
690 for (; aIt.More(); aIt.Next()) {
693 // take the first having occured inner link
695 const GEOMAlgo_PassKey& aPK=aIt.Key();
699 pIds=(Standard_Integer*)aPK.Key();
700 aN1=*(pIds+aNbMax-1);
701 aN2=*(pIds+aNbMax-2);
704 aN1=(Standard_Integer)aPK.Id(1);
705 aN2=(Standard_Integer)aPK.Id(2);
707 aP1=aNodes(aN1).Transformed(aTrsf);
708 aP2=aNodes(aN2).Transformed(aTrsf);
710 if (aType==GeomAbs_Cylinder) {
711 Standard_Real aTolSM;
714 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
715 aCyl=aGAS.Cylinder();
716 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
721 BRepLib_MakeEdge aBME(aP1, aP2);
722 bIsDone=aBME.IsDone();
724 myErrorStatus=30; //can not obtain the line fron the link
728 const TopoDS_Shape& aSx=aBME.Shape();
729 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
731 InnerPoints(aE, myNbPntsMin, aLP);
734 }// for (; aIt.More(); aIt.Next())
735 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
736 }// if (!aNb && myNbPntsMin) {
738 //=======================================================================
739 //function : InnerPoints
741 //=======================================================================
742 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
743 GEOMAlgo_ListOfPnt& aLP)
747 Standard_Integer j, aNbNodes, aIndex, aNb;
748 Handle(Poly_PolygonOnTriangulation) aPTE;
749 Handle(Poly_Triangulation) aTRE;
750 TopLoc_Location aLoc;
754 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
755 if (aTRE.IsNull() || aPTE.IsNull()) {
756 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
758 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
759 myErrorStatus=20; // no triangulation found
762 aPE = BRep_Tool::Polygon3D(aE, aLoc);
764 const gp_Trsf& aTrsf=aLoc.Transformation();
765 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
767 aNbNodes=aPE->NbNodes();
768 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
769 for (j=low+1; j<up; ++j) {
770 aP=aNodes(j).Transformed(aTrsf);
775 const gp_Trsf& aTrsf=aLoc.Transformation();
776 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
778 aNbNodes=aPTE->NbNodes();
779 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
780 for (j=2; j<aNbNodes; ++j) {
782 aP=aNodes(aIndex).Transformed(aTrsf);
788 if (!aNb && myNbPntsMin) {
789 // try to fill it yourself
790 InnerPoints(aE, myNbPntsMin, aLP);
794 //=======================================================================
795 //function : InnerPoints
797 //=======================================================================
798 void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
799 const Standard_Integer aNbPntsMin,
800 GEOMAlgo_ListOfPnt& aLP)
802 // try to fill it yourself
803 Standard_Boolean bInf1, bInf2;
804 Standard_Integer j, aNbT;
805 Standard_Real dT, aT, aT1, aT2;
807 Handle(Geom_Curve) aC3D;
809 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
814 bInf1=Precision::IsNegativeInfinite(aT1);
815 bInf2=Precision::IsPositiveInfinite(aT2);
816 if (bInf1 || bInf2) {
822 for (j=1; j<=aNbPntsMin; ++j) {
834 // 12 -unallowed type of subshapes
835 // 13 -unallowed state
836 // 15 -unallowed surface type
837 // 20- no triangulation found
838 // 30- can not obtain the line from the link
839 // 40- point can not be classified
840 // 41- invalid data for classifier