1 // Copyright (C) 2007-2012 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
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>
73 #include <GEOMAlgo_SurfaceTools.hxx>
74 #include <GEOMAlgo_StateCollector.hxx>
75 #include <GEOMAlgo_FinderShapeOn.hxx>
77 #include <GEOMAlgo_PassKey.hxx>
78 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
79 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
81 //=======================================================================
82 //function : GEOMAlgo_FinderShapeOn1
84 //=======================================================================
85 GEOMAlgo_FinderShapeOn1::GEOMAlgo_FinderShapeOn1()
90 myShapeType=TopAbs_VERTEX;
91 myState=GEOMAlgo_ST_UNKNOWN;
95 //=======================================================================
98 //=======================================================================
99 GEOMAlgo_FinderShapeOn1::~GEOMAlgo_FinderShapeOn1()
102 //=======================================================================
103 //function : SetSurface
105 //=======================================================================
106 void GEOMAlgo_FinderShapeOn1::SetSurface(const Handle(Geom_Surface)& aS)
110 //=======================================================================
113 //=======================================================================
114 const Handle(Geom_Surface)& GEOMAlgo_FinderShapeOn1::Surface() const
118 //=======================================================================
119 //function : SetShapeType
121 //=======================================================================
122 void GEOMAlgo_FinderShapeOn1::SetShapeType(const TopAbs_ShapeEnum aType)
126 //=======================================================================
127 //function : ShapeType
129 //=======================================================================
130 TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn1::ShapeType()const
134 //=======================================================================
135 //function : SetState
137 //=======================================================================
138 void GEOMAlgo_FinderShapeOn1::SetState(const GEOMAlgo_State aState)
142 //=======================================================================
145 //=======================================================================
146 GEOMAlgo_State GEOMAlgo_FinderShapeOn1::State() const
150 //=======================================================================
151 //function : SetNbPntsMin
153 //=======================================================================
154 void GEOMAlgo_FinderShapeOn1::SetNbPntsMin(const Standard_Integer aNb)
158 //=======================================================================
159 //function : NbPntsMin
161 //=======================================================================
162 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMin()const
166 //=======================================================================
167 //function : SetNbPntsMax
169 //=======================================================================
170 void GEOMAlgo_FinderShapeOn1::SetNbPntsMax(const Standard_Integer aNb)
174 //=======================================================================
175 //function : NbPntsMax
177 //=======================================================================
178 Standard_Integer GEOMAlgo_FinderShapeOn1::NbPntsMax()const
182 //=======================================================================
185 //=======================================================================
186 const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn1::MSS() const
190 //=======================================================================
193 //=======================================================================
194 const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn1::Shapes() const
196 Standard_Integer i, aNb;
197 TopTools_ListOfShape* pL;
199 pL=(TopTools_ListOfShape*) &myLS;
203 for (i=1; i<=aNb; ++i) {
204 const TopoDS_Shape& aS=myMSS.FindKey(i);
205 if (aS.ShapeType()==myShapeType) {
211 //=======================================================================
214 //=======================================================================
215 void GEOMAlgo_FinderShapeOn1::Perform()
227 // Initialize the context
228 GEOMAlgo_ShapeAlgo::Perform();
235 if (myShapeType==TopAbs_VERTEX) {
244 if (myShapeType==TopAbs_EDGE) {
253 if (myShapeType==TopAbs_FACE) {
261 //=======================================================================
262 //function : ProcessVertices
264 //=======================================================================
265 void GEOMAlgo_FinderShapeOn1::ProcessVertices()
269 Standard_Boolean bIsConformState;
270 Standard_Integer i, aNb;
272 TopTools_IndexedMapOfShape aM;
275 TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
277 for (i=1; i<=aNb; ++i) {
278 const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
279 aP=BRep_Tool::Pnt(aV);
281 aSt = GetPointState( aP );
282 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
284 if (myShapeType==TopAbs_VERTEX){
285 if (bIsConformState) {
289 else if (bIsConformState || aSt==TopAbs_ON) {
294 //=======================================================================
295 //function : ProcessEdges
297 //=======================================================================
298 void GEOMAlgo_FinderShapeOn1::ProcessEdges()
302 Standard_Boolean bIsConformState, bIsToBreak;
303 Standard_Integer i, aNb, iCnt;
305 TopTools_IndexedMapOfShape aM;
306 TopExp_Explorer aExp;
307 GEOMAlgo_ListIteratorOfListOfPnt aIt;
308 GeomAbs_SurfaceType aType1;
310 aType1=myGAS.GetType();
312 TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
314 for (i=1; i<=aNb; ++i) {
315 GEOMAlgo_ListOfPnt aLP;
316 GEOMAlgo_StateCollector aSC;
318 const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
320 aExp.Init(aE, TopAbs_VERTEX);
321 for (; aExp.More(); aExp.Next()) {
322 const TopoDS_Shape& aV=aExp.Current();
324 bIsConformState=myMSS.Contains(aV);
325 if (!bIsConformState) {
326 break;// vertex has non-conformed state
329 aSt=myMSS.FindFromKey(aV);
330 aSC.AppendState(aSt);
334 if (!bIsConformState) {
335 continue; // vertex has non-conformed state,skip edge
338 if (BRep_Tool::Degenerated(aE)) {
343 if (myState==GEOMAlgo_ST_ON && aType1==GeomAbs_Sphere) {
344 Standard_Real aT1, aT2;
345 Handle(Geom_Curve) aC;
346 GeomAdaptor_Curve aGAC;
347 GeomAbs_CurveType aType2;
349 aC=BRep_Tool::Curve(aE, aT1, aT2);
352 aType2=aGAC.GetType();
353 if (aType2==GeomAbs_Line) {
358 InnerPoints(aE, aLP);
363 bIsConformState=Standard_True;
365 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
367 if (iCnt > myNbPntsMax) {
372 const gp_Pnt& aP=aIt.Value();
373 aSt = GetPointState( aP );
374 bIsToBreak=aSC.AppendState(aSt);
382 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
383 if (myShapeType==TopAbs_EDGE) {
384 if (bIsConformState) {
388 else if (bIsConformState || aSt==TopAbs_ON) {
391 } // for (i=1; i<=aNb; ++i) next edge
393 //=======================================================================
394 //function : ProcessFaces
396 //=======================================================================
397 void GEOMAlgo_FinderShapeOn1::ProcessFaces()
401 Standard_Boolean bIsConformState, bIsToBreak;
402 Standard_Integer i, aNbF, iCnt;
404 TopTools_IndexedMapOfShape aM;
405 TopExp_Explorer aExp;
406 GEOMAlgo_ListIteratorOfListOfPnt aIt;
407 GeomAbs_SurfaceType aType1, aType2;
409 aType1=myGAS.GetType();
411 TopExp::MapShapes(myShape, TopAbs_FACE, aM);
413 for (i=1; i<=aNbF; ++i) {
414 GEOMAlgo_StateCollector aSC;
415 GEOMAlgo_ListOfPnt aLP;
417 const TopoDS_Face& aF=TopoDS::Face(aM(i));
419 if (myState==GEOMAlgo_ST_ON) {
420 Handle(Geom_Surface) aS;
421 GeomAdaptor_Surface aGAS;
423 aS=BRep_Tool::Surface(aF);
425 aType2=aGAS.GetType();
426 if (aType2!=aType1) {
431 aExp.Init(aF, TopAbs_EDGE);
432 for (; aExp.More(); aExp.Next()) {
433 const TopoDS_Shape& aE=aExp.Current();
434 bIsConformState=myMSS.Contains(aE);
435 if (!bIsConformState) {
436 break;// edge has non-conformed state
439 aSt=myMSS.FindFromKey(aE);
440 aSC.AppendState(aSt);
444 if (!bIsConformState) {
445 continue; // edge has non-conformed state,skip face
448 InnerPoints(aF, aLP);
453 bIsConformState=Standard_True;
455 for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
457 if (iCnt > myNbPntsMax) {
462 const gp_Pnt& aP=aIt.Value();
463 aSt = GetPointState( aP );
464 bIsToBreak=aSC.AppendState(aSt);
472 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
473 if (myShapeType==TopAbs_FACE) {
474 if (bIsConformState) {
478 else if (bIsConformState || aSt==TopAbs_ON) {
481 }// for (i=1; i<=aNb; ++i) next face
483 //=======================================================================
484 //function : ProcessSolids
486 //=======================================================================
487 void GEOMAlgo_FinderShapeOn1::ProcessSolids()
491 Standard_Boolean bIsConformState;
492 Standard_Integer i, aNbS, j, aNbF;
493 TopTools_IndexedMapOfShape aM, aMF;
496 TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
498 for (i=1; i<=aNbS; ++i) {
499 GEOMAlgo_StateCollector aSC;
501 const TopoDS_Shape& aSd=aM(i);
503 TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
505 for (j=1; j<=aNbF; ++j) {
506 const TopoDS_Shape& aF=aMF(j);
507 bIsConformState=myMSS.Contains(aF);
508 if (!bIsConformState) {
509 break;// face has non-conformed state
512 aSt=myMSS.FindFromKey(aF);
513 aSC.AppendState(aSt);
517 if (!bIsConformState) {
518 continue; // face has non-conformed state,skip solid
523 bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
524 if (bIsConformState) {
530 //=======================================================================
531 //function : InnerPoints
533 //=======================================================================
534 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Face& aF,
535 GEOMAlgo_ListOfPnt& aLP)
539 Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
540 TopLoc_Location aLoc;
541 Handle(Poly_Triangulation) aTRF;
542 TColStd_MapOfInteger aMBN;
543 GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
544 GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
549 aTRF=BRep_Tool::Triangulation(aF, aLoc);
551 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
552 myWarningStatus=20; // no triangulation found
555 aTRF=BRep_Tool::Triangulation(aF, aLoc);
558 const gp_Trsf& aTrsf=aLoc.Transformation();
559 const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
560 const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
562 // map link/nbtriangles
565 for (j=j1; j<=j2; ++j) {
566 const Poly_Triangle& aTr=aTrs(j);
567 aTr.Get(n[0], n[1], n[2]);
569 for (k=0; k<3; ++k) {
570 GEOMAlgo_PassKey aPK;
572 aPK.SetIds(n[k], n[k+1]);
573 if (aMPKI.IsBound(aPK)) {
574 Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
583 // boundary nodes aMBN
584 aNbLinks=aMPKI.Extent();
585 aIt.Initialize(aMPKI);
586 for (; aIt.More(); aIt.Next()) {
589 const GEOMAlgo_PassKey& aPK=aIt.Key();
591 aNx=(Standard_Integer)aPK.Id(1);
593 aNx=(Standard_Integer)aPK.Id(2);
598 // inner nodes=all_nodes - boundary_nodes
601 for (j=j1; j<=j2; ++j) {
602 if (!aMBN.Contains(j)) {
603 aP=aNodes(j).Transformed(aTrsf);
610 if (!aNb && myNbPntsMin) {
611 // try to fill it yourself
612 Standard_Boolean bIsDone;
613 Standard_Integer aN1, aN2;
614 Handle(Geom_Surface) aS;
615 GeomAdaptor_Surface aGAS;
616 GeomAbs_SurfaceType aType;
618 aS=BRep_Tool::Surface(aF);
620 aType=aGAS.GetType();
621 if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
623 aNbLinks=aMPKI.Extent();
624 aIt.Initialize(aMPKI);
625 for (; aIt.More(); aIt.Next()) {
628 // take the first having occured inner link
630 const GEOMAlgo_PassKey& aPK=aIt.Key();
632 aN1=(Standard_Integer)aPK.Id(1);
633 aN2=(Standard_Integer)aPK.Id(2);
635 aP1=aNodes(aN1).Transformed(aTrsf);
636 aP2=aNodes(aN2).Transformed(aTrsf);
638 if (aType==GeomAbs_Cylinder) {
639 Standard_Real aTolSM;
642 aTolSM=1.523e-6;//~1.-cos(0.1 deg)
643 aCyl=aGAS.Cylinder();
644 if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
649 BRepLib_MakeEdge aBME(aP1, aP2);
650 bIsDone=aBME.IsDone();
652 myErrorStatus=30; //can not obtain the line fron the link
656 const TopoDS_Shape& aSx=aBME.Shape();
657 const TopoDS_Edge& aE=TopoDS::Edge(aSx);
659 InnerPoints(aE, myNbPntsMin, aLP);
662 }// for (; aIt.More(); aIt.Next())
663 }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
664 }// if (!aNb && myNbPntsMin) {
666 //modified by NIZNHY-PKV Thu Jan 26 09:56:20 2012f
667 //=======================================================================
668 //function : InnerPoints
670 //=======================================================================
671 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
672 GEOMAlgo_ListOfPnt& aLP)
674 Standard_Integer aNbPntsMin;
680 InnerPoints(aE, aNbPntsMin, aLP);
682 //modified by NIZNHY-PKV Thu Jan 26 09:56:32 2012t
683 //=======================================================================
684 //function : InnerPoints
686 //=======================================================================
687 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
688 const Standard_Integer aNbPntsMin,
689 GEOMAlgo_ListOfPnt& aLP)
691 Standard_Boolean bInf1, bInf2;
692 Standard_Integer j, aNbT;
693 Standard_Real dT, aT, aT1, aT2;
695 Handle(Geom_Curve) aC3D;
697 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
702 bInf1=Precision::IsNegativeInfinite(aT1);
703 bInf2=Precision::IsPositiveInfinite(aT2);
704 if (bInf1 || bInf2) {
708 //modified by NIZNHY-PKV Thu Jan 26 09:51:20 2012f
712 for (j=1; j<=aNbPntsMin; ++j) {
720 for (j=1; j<aNbT; ++j) {
725 //modified by NIZNHY-PKV Thu Jan 26 09:51:24 2012t
728 //=======================================================================
729 //function : CheckData
731 //=======================================================================
732 void GEOMAlgo_FinderShapeOn1::CheckData()
736 if(mySurface.IsNull()) {
737 myErrorStatus=10; // mySurface=NULL
741 if (myShape.IsNull()) {
742 myErrorStatus=11; // myShape=NULL
746 if (!(myShapeType==TopAbs_VERTEX ||
747 myShapeType==TopAbs_EDGE ||
748 myShapeType==TopAbs_FACE ||
749 myShapeType==TopAbs_SOLID)) {
750 myErrorStatus=12; // unallowed subshape type
754 if (myState==GEOMAlgo_ST_UNKNOWN ||
755 myState==GEOMAlgo_ST_INOUT) {
756 myErrorStatus=13; // unallowed state type
760 GeomAbs_SurfaceType aType;
762 myGAS.Load(mySurface);
763 aType=myGAS.GetType();
764 if (!(aType==GeomAbs_Plane ||
765 aType==GeomAbs_Cylinder ||
766 aType==GeomAbs_Sphere)) {
767 myErrorStatus=14; // unallowed surface type
771 //=======================================================================
772 //function : GetPointState
774 //=======================================================================
776 TopAbs_State GEOMAlgo_FinderShapeOn1::GetPointState(const gp_Pnt& aP)
779 GEOMAlgo_SurfaceTools::GetState(aP, myGAS, myTolerance, aSt);
787 // 10 -mySurface=NULL
789 // 12 -unallowed type of subshapes
790 // 13 -unallowed state
791 // 14 -unallowed surface type
792 // 15 -unallowed surface type
793 // 20- no triangulation found
794 // 30- can not obtain the line from the link
796 //modified by NIZNHY-PKV Thu Jan 26 10:01:14 2012f
798 //=======================================================================
799 //function : InnerPoints
801 //=======================================================================
802 void GEOMAlgo_FinderShapeOn1::InnerPoints(const TopoDS_Edge& aE,
803 GEOMAlgo_ListOfPnt& aLP)
807 Standard_Integer j, aNbNodes, aIndex, aNb;
808 Handle(Poly_PolygonOnTriangulation) aPTE;
809 Handle(Poly_Triangulation) aTRE;
810 TopLoc_Location aLoc;
814 BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
815 if (aTRE.IsNull() || aPTE.IsNull()) {
816 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
818 if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
819 myErrorStatus=20; // no triangulation found
822 aPE = BRep_Tool::Polygon3D(aE, aLoc);
824 const gp_Trsf& aTrsf=aLoc.Transformation();
825 const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
827 aNbNodes=aPE->NbNodes();
828 Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
829 for (j=low+1; j<up; ++j) {
830 aP=aNodes(j).Transformed(aTrsf);
835 const gp_Trsf& aTrsf=aLoc.Transformation();
836 const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
838 aNbNodes=aPTE->NbNodes();
839 const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
840 for (j=2; j<aNbNodes; ++j) {
842 aP=aNodes(aIndex).Transformed(aTrsf);
848 if (!aNb && myNbPntsMin) {
849 // try to fill it yourself
850 InnerPoints(aE, myNbPntsMin, aLP);
855 //modified by NIZNHY-PKV Thu Jan 26 10:01:17 2012t