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 : GEOMImpl_IShapesOperations.cxx
25 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
29 #include <Standard_Stream.hxx>
31 #include "GEOMImpl_IShapesOperations.hxx"
33 #include "GEOMImpl_Types.hxx"
35 #include "GEOMImpl_VectorDriver.hxx"
36 #include "GEOMImpl_ShapeDriver.hxx"
37 #include "GEOMImpl_CopyDriver.hxx"
38 #include "GEOMImpl_GlueDriver.hxx"
40 #include "GEOMImpl_IVector.hxx"
41 #include "GEOMImpl_IShapes.hxx"
42 #include "GEOMImpl_IGlue.hxx"
44 #include "GEOMImpl_Block6Explorer.hxx"
46 #include "GEOM_Function.hxx"
47 #include "GEOM_ISubShape.hxx"
48 #include "GEOM_PythonDump.hxx"
50 #include "GEOMAlgo_FinderShapeOn1.hxx"
51 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
52 #include "GEOMAlgo_FinderShapeOn2.hxx"
53 #include "GEOMAlgo_ClsfBox.hxx"
54 #include "GEOMAlgo_ClsfSolid.hxx"
55 #include "GEOMAlgo_Gluer1.hxx"
56 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
57 #include "GEOMAlgo_CoupleOfShapes.hxx"
58 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
60 #include "utilities.h"
62 #include "Utils_ExceptHandlers.hxx"
64 #include <TFunction_DriverTable.hxx>
65 #include <TFunction_Driver.hxx>
66 #include <TFunction_Logbook.hxx>
67 #include <TDataStd_Integer.hxx>
68 #include <TDataStd_IntegerArray.hxx>
69 #include <TDF_Tool.hxx>
71 #include <BRepExtrema_ExtCF.hxx>
72 #include <BRepExtrema_DistShapeShape.hxx>
74 #include <BRep_Tool.hxx>
75 #include <BRep_Builder.hxx>
76 #include <BRepTools.hxx>
77 #include <BRepGProp.hxx>
78 #include <BRepAdaptor_Curve.hxx>
79 #include <BRepAdaptor_Surface.hxx>
80 #include <BRepBndLib.hxx>
81 #include <BRepBuilderAPI_MakeFace.hxx>
82 #include <BRepMesh_IncrementalMesh.hxx>
87 #include <TopoDS_Shape.hxx>
88 #include <TopoDS_Solid.hxx>
89 #include <TopoDS_Face.hxx>
90 #include <TopoDS_Edge.hxx>
91 #include <TopoDS_Vertex.hxx>
92 #include <TopoDS_Compound.hxx>
93 #include <TopoDS_Iterator.hxx>
94 #include <TopExp_Explorer.hxx>
95 #include <TopLoc_Location.hxx>
96 #include <TopTools_MapOfShape.hxx>
97 #include <TopTools_MapOfOrientedShape.hxx>
98 #include <TopTools_Array1OfShape.hxx>
99 #include <TopTools_ListIteratorOfListOfShape.hxx>
100 #include <TopTools_IndexedMapOfShape.hxx>
102 #include <Geom_Surface.hxx>
103 #include <Geom_Plane.hxx>
104 #include <Geom_SphericalSurface.hxx>
105 #include <Geom_CylindricalSurface.hxx>
106 #include <GeomAdaptor_Surface.hxx>
108 #include <GeomLib_Tool.hxx>
109 #include <Geom2d_Curve.hxx>
111 #include <Bnd_Box.hxx>
112 #include <GProp_GProps.hxx>
113 #include <TColStd_Array1OfReal.hxx>
114 #include <TColStd_HArray1OfInteger.hxx>
115 #include <TColStd_ListIteratorOfListOfInteger.hxx>
116 #include <TColStd_ListOfInteger.hxx>
117 #include <gp_Cylinder.hxx>
118 #include <gp_Lin.hxx>
119 #include <gp_Pnt.hxx>
123 #include <Standard_NullObject.hxx>
124 #include <Standard_Failure.hxx>
125 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
127 // Includes added for GetInPlace algorithm improvement
129 #include <GEOMImpl_MeasureDriver.hxx>
130 #include <GEOMImpl_IMeasure.hxx>
131 #include <BRepBuilderAPI_MakeVertex.hxx>
133 #include <BRepClass_FaceClassifier.hxx>
134 #include <BRepClass3d_SolidClassifier.hxx>
135 #include <Precision.hxx>
137 //=============================================================================
141 //=============================================================================
142 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
143 : GEOM_IOperations(theEngine, theDocID)
145 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
148 //=============================================================================
152 //=============================================================================
153 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
155 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
158 //=============================================================================
162 //=============================================================================
163 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
164 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
168 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
170 //Add a new Edge object
171 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
173 //Add a new Vector function
174 Handle(GEOM_Function) aFunction =
175 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
177 //Check if the function is set correctly
178 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
180 GEOMImpl_IVector aPI (aFunction);
182 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
183 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
184 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
186 aPI.SetPoint1(aRef1);
187 aPI.SetPoint2(aRef2);
189 //Compute the Edge value
191 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
194 if (!GetSolver()->ComputeFunction(aFunction)) {
195 SetErrorCode("Vector driver failed");
199 catch (Standard_Failure) {
200 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
201 SetErrorCode(aFail->GetMessageString());
205 //Make a Python command
206 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
207 << thePnt1 << ", " << thePnt2 << ")";
213 //=============================================================================
217 //=============================================================================
218 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
219 (std::list<Handle(GEOM_Object)> theShapes,
220 const Standard_Real theTolerance)
225 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
228 Handle(GEOM_Function) aFunction =
229 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
230 if (aFunction.IsNull()) return NULL;
232 //Check if the function is set correctly
233 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
235 GEOMImpl_IShapes aCI (aFunction);
236 aCI.SetTolerance(theTolerance);
238 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
241 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
242 for (; it != theShapes.end(); it++) {
243 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
244 if (aRefSh.IsNull()) {
245 SetErrorCode("NULL argument shape for the shape construction");
248 aShapesSeq->Append(aRefSh);
250 aCI.SetShapes(aShapesSeq);
254 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
257 if (!GetSolver()->ComputeFunction(aFunction)) {
258 SetErrorCode("Shape driver failed");
262 catch (Standard_Failure) {
263 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
264 SetErrorCode(aFail->GetMessageString());
268 //Make a Python command
269 GEOM::TPythonDump pd (aFunction);
270 pd << aWire << " = geompy.MakeWire([";
273 it = theShapes.begin();
274 if (it != theShapes.end()) {
276 while (it != theShapes.end()) {
277 pd << ", " << (*it++);
280 pd << "], " << theTolerance << ")";
286 //=============================================================================
290 //=============================================================================
291 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
292 const bool isPlanarWanted)
296 if (theWire.IsNull()) return NULL;
298 //Add a new Face object
299 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
301 //Add a new Shape function for creation of a face from a wire
302 Handle(GEOM_Function) aFunction =
303 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
304 if (aFunction.IsNull()) return NULL;
306 //Check if the function is set correctly
307 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
309 GEOMImpl_IShapes aCI (aFunction);
311 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
313 if (aRefWire.IsNull()) return NULL;
315 aCI.SetBase(aRefWire);
316 aCI.SetIsPlanar(isPlanarWanted);
318 //Compute the Face value
320 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
323 if (!GetSolver()->ComputeFunction(aFunction)) {
324 SetErrorCode("Shape driver failed to compute a face");
328 catch (Standard_Failure) {
329 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
330 SetErrorCode(aFail->GetMessageString());
334 //Make a Python command
335 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
336 << theWire << ", " << (int)isPlanarWanted << ")";
342 //=============================================================================
346 //=============================================================================
347 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
348 (std::list<Handle(GEOM_Object)> theShapes,
349 const bool isPlanarWanted)
354 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
357 Handle(GEOM_Function) aFunction =
358 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
359 if (aFunction.IsNull()) return NULL;
361 //Check if the function is set correctly
362 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
364 GEOMImpl_IShapes aCI (aFunction);
366 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
369 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
370 for (; it != theShapes.end(); it++) {
371 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
372 if (aRefSh.IsNull()) {
373 SetErrorCode("NULL argument shape for the face construction");
376 aShapesSeq->Append(aRefSh);
378 aCI.SetShapes(aShapesSeq);
380 aCI.SetIsPlanar(isPlanarWanted);
384 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
387 if (!GetSolver()->ComputeFunction(aFunction)) {
388 SetErrorCode("Shape driver failed");
392 catch (Standard_Failure) {
393 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
394 SetErrorCode(aFail->GetMessageString());
398 //Make a Python command
399 GEOM::TPythonDump pd (aFunction);
400 pd << aShape << " = geompy.MakeFaceWires([";
403 it = theShapes.begin();
404 if (it != theShapes.end()) {
406 while (it != theShapes.end()) {
407 pd << ", " << (*it++);
410 pd << "], " << (int)isPlanarWanted << ")";
416 //=============================================================================
420 //=============================================================================
421 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
422 (std::list<Handle(GEOM_Object)> theShapes)
424 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
427 //=============================================================================
431 //=============================================================================
432 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
433 (std::list<Handle(GEOM_Object)> theShapes)
435 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
438 //=============================================================================
442 //=============================================================================
443 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
447 if (theShell.IsNull()) return NULL;
449 //Add a new Solid object
450 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
452 //Add a new Solid function for creation of a solid from a shell
453 Handle(GEOM_Function) aFunction =
454 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
455 if (aFunction.IsNull()) return NULL;
457 //Check if the function is set correctly
458 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
460 GEOMImpl_IShapes aCI (aFunction);
462 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
464 if (aRefShell.IsNull()) return NULL;
466 aCI.SetBase(aRefShell);
468 //Compute the Solid value
470 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
473 if (!GetSolver()->ComputeFunction(aFunction)) {
474 SetErrorCode("Solid driver failed");
478 catch (Standard_Failure) {
479 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
480 SetErrorCode(aFail->GetMessageString());
484 //Make a Python command
485 GEOM::TPythonDump(aFunction) << aSolid
486 << " = geompy.MakeSolid(" << theShell << ")";
492 //=============================================================================
496 //=============================================================================
497 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
498 (std::list<Handle(GEOM_Object)> theShapes)
500 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
503 //=============================================================================
507 //=============================================================================
508 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
509 (std::list<Handle(GEOM_Object)> theShapes,
510 const Standard_Integer theObjectType,
511 const Standard_Integer theFunctionType,
512 const TCollection_AsciiString& theMethodName)
517 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
520 Handle(GEOM_Function) aFunction =
521 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
522 if (aFunction.IsNull()) return NULL;
524 //Check if the function is set correctly
525 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
527 GEOMImpl_IShapes aCI (aFunction);
529 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
532 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
533 for (; it != theShapes.end(); it++) {
534 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
535 if (aRefSh.IsNull()) {
536 SetErrorCode("NULL argument shape for the shape construction");
539 aShapesSeq->Append(aRefSh);
541 aCI.SetShapes(aShapesSeq);
545 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
548 if (!GetSolver()->ComputeFunction(aFunction)) {
549 SetErrorCode("Shape driver failed");
553 catch (Standard_Failure) {
554 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
555 SetErrorCode(aFail->GetMessageString());
559 //Make a Python command
560 GEOM::TPythonDump pd (aFunction);
561 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
564 it = theShapes.begin();
565 if (it != theShapes.end()) {
567 while (it != theShapes.end()) {
568 pd << ", " << (*it++);
577 //=============================================================================
581 //=============================================================================
582 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
583 (Handle(GEOM_Object) theShape,
584 const Standard_Real theTolerance,
585 const Standard_Boolean doKeepNonSolids)
589 if (theShape.IsNull()) return NULL;
591 //Add a new Glued object
592 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
594 //Add a new Glue function
595 Handle(GEOM_Function) aFunction;
596 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
597 if (aFunction.IsNull()) return NULL;
599 //Check if the function is set correctly
600 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
602 GEOMImpl_IGlue aCI (aFunction);
604 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
605 if (aRefShape.IsNull()) return NULL;
607 aCI.SetBase(aRefShape);
608 aCI.SetTolerance(theTolerance);
609 aCI.SetKeepNonSolids(doKeepNonSolids);
611 //Compute the sub-shape value
612 Standard_Boolean isWarning = Standard_False;
614 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
617 if (!GetSolver()->ComputeFunction(aFunction)) {
618 SetErrorCode("Shape driver failed to glue faces");
622 catch (Standard_Failure) {
623 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
624 SetErrorCode(aFail->GetMessageString());
625 // to provide warning
626 if (!aFunction->GetValue().IsNull()) {
627 isWarning = Standard_True;
633 //Make a Python command
634 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
635 << theShape << ", " << theTolerance << ")";
637 // to provide warning
638 if (!isWarning) SetErrorCode(OK);
642 //=============================================================================
646 //=============================================================================
647 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
648 (Handle(GEOM_Object) theShape,
649 const Standard_Real theTolerance)
653 if (theShape.IsNull()) return NULL;
654 TopoDS_Shape aShape = theShape->GetValue();
655 if (aShape.IsNull()) return NULL;
657 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
659 Standard_Integer iErr;
661 GEOMAlgo_Gluer1 aGluer;
662 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
663 GEOMAlgo_CoupleOfShapes aCS;
664 GEOMAlgo_ListOfCoupleOfShapes aLCS;
666 //aGluer = new GEOMAlgo_Gluer1;
667 aGluer.SetShape(aShape);
668 aGluer.SetTolerance(theTolerance);
670 iErr = aGluer.ErrorStatus();
671 if (iErr) return NULL;
673 TopTools_ListOfShape listShape;
674 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
676 aItCS.Initialize(aLCSG);
677 for (; aItCS.More(); aItCS.Next()) {
678 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
679 listShape.Append(aCSG.Shape1());
682 TopTools_ListIteratorOfListOfShape itSub (listShape);
683 TCollection_AsciiString anAsciiList, anEntry;
684 TopTools_IndexedMapOfShape anIndices;
685 TopExp::MapShapes(aShape, anIndices);
686 Handle(TColStd_HArray1OfInteger) anArray;
687 Handle(GEOM_Object) anObj;
688 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
689 TopoDS_Shape aValue = itSub.Value();
690 anArray = new TColStd_HArray1OfInteger(1,1);
691 anArray->SetValue(1, anIndices.FindIndex(aValue));
692 anObj = GetEngine()->AddSubShape(theShape, anArray);
693 if (!anObj.IsNull()) {
696 // for python command
697 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
698 anAsciiList += anEntry;
703 //Make a Python command
704 if( anAsciiList.Length() > 0 ) {
705 anAsciiList.Trunc(anAsciiList.Length() - 1);
706 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
707 GEOM::TPythonDump pd (aFunction, /*append=*/true);
708 pd << "[" << anAsciiList.ToCString();
709 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
717 //=============================================================================
719 * MakeGlueFacesByList
721 //=============================================================================
722 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
723 (Handle(GEOM_Object) theShape,
724 const Standard_Real theTolerance,
725 std::list<Handle(GEOM_Object)> theFaces,
726 const Standard_Boolean doKeepNonSolids)
730 if (theShape.IsNull()) return NULL;
732 //Add a new Glued object
733 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
735 //Add a new Glue function
736 Handle(GEOM_Function) aFunction;
737 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
738 if (aFunction.IsNull()) return NULL;
740 //Check if the function is set correctly
741 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
743 GEOMImpl_IGlue aCI (aFunction);
745 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
746 if (aRefShape.IsNull()) return NULL;
748 aCI.SetBase(aRefShape);
749 aCI.SetTolerance(theTolerance);
750 aCI.SetKeepNonSolids(doKeepNonSolids);
752 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
753 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
754 for (; it != theFaces.end(); it++) {
755 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
756 if (aRefSh.IsNull()) {
757 SetErrorCode("NULL argument shape for the shape construction");
760 aFaces->Append(aRefSh);
762 aCI.SetFaces(aFaces);
764 //Compute the sub-shape value
765 Standard_Boolean isWarning = Standard_False;
767 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
770 if (!GetSolver()->ComputeFunction(aFunction)) {
771 SetErrorCode("Shape driver failed to glue faces");
775 catch (Standard_Failure) {
776 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
777 SetErrorCode(aFail->GetMessageString());
778 // to provide warning
779 if (!aFunction->GetValue().IsNull()) {
780 isWarning = Standard_True;
786 //Make a Python command
788 GEOM::TPythonDump pd(aFunction);
789 pd << aGlued << " = geompy.MakeGlueFacesByList("
790 << theShape << ", " << theTolerance << ", [";
792 it = theFaces.begin();
793 if (it != theFaces.end()) {
795 while (it != theFaces.end()) {
796 pd << ", " << (*it++);
801 // to provide warning
802 if (!isWarning) SetErrorCode(OK);
806 //=============================================================================
810 //=============================================================================
811 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
812 (Handle(GEOM_Object) theShape,
813 const Standard_Integer theShapeType,
814 const Standard_Boolean isSorted)
818 if (theShape.IsNull()) return NULL;
819 TopoDS_Shape aShape = theShape->GetValue();
820 if (aShape.IsNull()) return NULL;
822 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
824 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
825 Handle(GEOM_Object) anObj;
826 TopTools_MapOfShape mapShape;
827 TopTools_ListOfShape listShape;
829 if (aShape.ShapeType() == TopAbs_COMPOUND &&
830 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
831 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
832 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
833 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
834 for (; It.More(); It.Next()) {
835 if (mapShape.Add(It.Value())) {
836 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
837 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
838 listShape.Append(It.Value());
843 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
844 for (; exp.More(); exp.Next())
845 if (mapShape.Add(exp.Current()))
846 listShape.Append(exp.Current());
849 if (listShape.IsEmpty()) {
850 //SetErrorCode("The given shape has no sub-shapes of the requested type");
851 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
856 SortShapes(listShape);
858 TopTools_IndexedMapOfShape anIndices;
859 TopExp::MapShapes(aShape, anIndices);
860 Handle(TColStd_HArray1OfInteger) anArray;
862 TopTools_ListIteratorOfListOfShape itSub (listShape);
863 TCollection_AsciiString anAsciiList, anEntry;
864 for (int index = 1; itSub.More(); itSub.Next(), ++index)
866 TopoDS_Shape aValue = itSub.Value();
867 anArray = new TColStd_HArray1OfInteger(1,1);
868 anArray->SetValue(1, anIndices.FindIndex(aValue));
870 //anObj = GetEngine()->AddSubShape(theShape, anArray);
872 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
873 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
874 if (aFunction.IsNull()) return aSeq;
876 GEOM_ISubShape aSSI (aFunction);
877 aSSI.SetMainShape(aMainShape);
878 aSSI.SetIndices(anArray);
880 // Set function value directly, as we know it.
881 // Usage of Solver here would lead to significant loss of time,
882 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
883 // on the main shape for each being calculated sub-shape separately.
884 aFunction->SetValue(aValue);
887 if (!anObj.IsNull()) {
890 // for python command
891 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
892 anAsciiList += anEntry;
897 //Make a Python command
898 anAsciiList.Trunc(anAsciiList.Length() - 1);
900 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
901 pd << "[" << anAsciiList.ToCString();
902 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
903 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
910 //=============================================================================
914 //=============================================================================
915 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
916 (Handle(GEOM_Object) theShape,
917 const Standard_Integer theShapeType,
918 const Standard_Boolean isSorted)
922 if (theShape.IsNull()) return NULL;
923 TopoDS_Shape aShape = theShape->GetValue();
924 if (aShape.IsNull()) return NULL;
926 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
927 TopTools_MapOfShape mapShape;
928 TopTools_ListOfShape listShape;
930 if (aShape.ShapeType() == TopAbs_COMPOUND &&
931 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
932 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
933 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
934 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
935 for (; It.More(); It.Next()) {
936 if (mapShape.Add(It.Value())) {
937 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
938 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
939 listShape.Append(It.Value());
944 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
945 for (; exp.More(); exp.Next())
946 if (mapShape.Add(exp.Current()))
947 listShape.Append(exp.Current());
950 if (listShape.IsEmpty()) {
951 //SetErrorCode("The given shape has no sub-shapes of the requested type");
952 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
957 SortShapes(listShape);
959 TopTools_IndexedMapOfShape anIndices;
960 TopExp::MapShapes(aShape, anIndices);
961 Handle(TColStd_HArray1OfInteger) anArray;
963 TopTools_ListIteratorOfListOfShape itSub (listShape);
964 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
965 TopoDS_Shape aValue = itSub.Value();
966 aSeq->Append(anIndices.FindIndex(aValue));
969 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
971 //Make a Python command
972 GEOM::TPythonDump pd (aFunction, /*append=*/true);
973 pd << "listSubShapeIDs = geompy.SubShapeAll";
974 pd << (isSorted ? "SortedIDs(" : "IDs(");
975 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
981 //=============================================================================
985 //=============================================================================
986 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
987 (Handle(GEOM_Object) theMainShape,
988 const Standard_Integer theID)
992 if (theMainShape.IsNull()) return NULL;
994 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
995 anArray->SetValue(1, theID);
996 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
997 if (anObj.IsNull()) {
998 SetErrorCode("Can not get a sub-shape with the given ID");
1002 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1004 //Make a Python command
1005 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1006 << theMainShape << ", [" << theID << "])";
1012 //=============================================================================
1016 //=============================================================================
1017 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1018 Handle(GEOM_Object) theSubShape)
1022 TopoDS_Shape aMainShape = theMainShape->GetValue();
1023 TopoDS_Shape aSubShape = theSubShape->GetValue();
1025 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1027 TopTools_IndexedMapOfShape anIndices;
1028 TopExp::MapShapes(aMainShape, anIndices);
1029 if (anIndices.Contains(aSubShape)) {
1031 return anIndices.FindIndex(aSubShape);
1037 //=============================================================================
1041 //=============================================================================
1042 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1043 Handle(GEOM_Object) theSubShape)
1047 TopoDS_Shape aMainShape = theMainShape->GetValue();
1048 TopoDS_Shape aSubShape = theSubShape->GetValue();
1050 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1051 SetErrorCode("Null argument shape given");
1056 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1058 TopTools_ListOfShape CL;
1059 CL.Append(aMainShape);
1060 TopTools_ListIteratorOfListOfShape itC;
1061 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1062 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1063 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1064 if (it.Value().IsSame(aSubShape))
1068 CL.Append(it.Value());
1073 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1074 TopTools_MapOfShape M;
1075 for (; anExp.More(); anExp.Next()) {
1076 if (M.Add(anExp.Current())) {
1077 if (anExp.Current().IsSame(aSubShape))
1084 SetErrorCode("The sub-shape does not belong to the main shape");
1088 //=============================================================================
1090 * GetShapeTypeString
1092 //=============================================================================
1093 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1097 TCollection_AsciiString aTypeName ("Null Shape");
1099 TopoDS_Shape aShape = theShape->GetValue();
1100 if (aShape.IsNull())
1103 switch (aShape.ShapeType() )
1105 case TopAbs_COMPOUND:
1106 aTypeName = "Compound";
1108 case TopAbs_COMPSOLID:
1109 aTypeName = "Compound Solid";
1112 aTypeName = "Solid";
1115 aTypeName = "Shell";
1119 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1120 if (surf.GetType() == GeomAbs_Plane)
1121 aTypeName = "Plane";
1122 else if (surf.GetType() == GeomAbs_Cylinder)
1123 aTypeName = "Cylindrical Face";
1124 else if (surf.GetType() == GeomAbs_Sphere)
1125 aTypeName = "Spherical Face";
1126 else if (surf.GetType() == GeomAbs_Torus)
1127 aTypeName = "Toroidal Face";
1128 else if (surf.GetType() == GeomAbs_Cone)
1129 aTypeName = "Conical Face";
1131 aTypeName = "GEOM::FACE";
1139 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1140 if (curv.GetType() == GeomAbs_Line) {
1141 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1142 (Abs(curv.LastParameter()) >= 1E6))
1146 } else if (curv.GetType() == GeomAbs_Circle) {
1147 if (curv.IsClosed())
1148 aTypeName = "Circle";
1157 aTypeName = "Vertex";
1160 aTypeName = "Shape";
1163 aTypeName = "Shape of unknown type";
1169 //=============================================================================
1173 //=============================================================================
1174 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1175 (Handle(GEOM_Object) theShape,
1176 const Standard_Integer theShapeType)
1179 Standard_Integer nbShapes = 0;
1181 if (theShape.IsNull()) return -1;
1182 TopoDS_Shape aShape = theShape->GetValue();
1183 if (aShape.IsNull()) return -1;
1186 TopTools_MapOfShape mapShape;
1188 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1189 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1190 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1191 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1192 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1193 for (; It.More(); It.Next()) {
1194 if (mapShape.Add(It.Value())) {
1195 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1196 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1202 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1203 for (; exp.More(); exp.Next())
1204 if (mapShape.Add(exp.Current()))
1210 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1213 int iType, nbTypes [TopAbs_SHAPE];
1214 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1216 nbTypes[aShape.ShapeType()]++;
1218 TopTools_MapOfShape aMapOfShape;
1219 aMapOfShape.Add(aShape);
1220 TopTools_ListOfShape aListOfShape;
1221 aListOfShape.Append(aShape);
1223 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1224 for (; itL.More(); itL.Next()) {
1225 TopoDS_Iterator it (itL.Value());
1226 for (; it.More(); it.Next()) {
1227 TopoDS_Shape s = it.Value();
1228 if (aMapOfShape.Add(s)) {
1229 aListOfShape.Append(s);
1230 nbTypes[s.ShapeType()]++;
1235 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1236 nbShapes = aMapOfShape.Extent();
1238 nbShapes = nbTypes[theShapeType];
1240 catch (Standard_Failure) {
1241 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1242 SetErrorCode(aFail->GetMessageString());
1250 //=============================================================================
1254 //=============================================================================
1255 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1259 if (theShape.IsNull()) return NULL;
1261 //Add a new reversed object
1262 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1264 //Add a new Revese function
1265 Handle(GEOM_Function) aFunction;
1266 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1267 if (aFunction.IsNull()) return NULL;
1269 //Check if the function is set correctly
1270 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1272 GEOMImpl_IShapes aSI (aFunction);
1274 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1275 if (aRefShape.IsNull()) return NULL;
1277 aSI.SetBase(aRefShape);
1279 //Compute the sub-shape value
1281 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1284 if (!GetSolver()->ComputeFunction(aFunction)) {
1285 SetErrorCode("Shape driver failed to reverse shape");
1289 catch (Standard_Failure) {
1290 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1291 SetErrorCode(aFail->GetMessageString());
1295 //Make a Python command
1296 GEOM::TPythonDump(aFunction) << aReversed
1297 << " = geompy.ChangeOrientation(" << theShape << ")";
1303 //=============================================================================
1307 //=============================================================================
1308 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1309 (Handle(GEOM_Object) theShape)
1313 if (theShape.IsNull()) return NULL;
1314 TopoDS_Shape aShape = theShape->GetValue();
1315 if (aShape.IsNull()) return NULL;
1317 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1319 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1320 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1321 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1323 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1326 SetErrorCode("The given shape has no faces");
1330 TopTools_IndexedMapOfShape anIndices;
1331 TopExp::MapShapes(aShape, anIndices);
1333 Standard_Integer id;
1334 for (; ind <= nbFaces; ind++) {
1335 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1336 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1341 //The explode doesn't change object so no new function is required.
1342 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1344 //Make a Python command
1345 GEOM::TPythonDump(aFunction, /*append=*/true)
1346 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1352 //=======================================================================
1353 //function : GetSharedShapes
1355 //=======================================================================
1356 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1357 (Handle(GEOM_Object) theShape1,
1358 Handle(GEOM_Object) theShape2,
1359 const Standard_Integer theShapeType)
1363 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1365 TopoDS_Shape aShape1 = theShape1->GetValue();
1366 TopoDS_Shape aShape2 = theShape2->GetValue();
1368 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1370 TopTools_IndexedMapOfShape anIndices;
1371 TopExp::MapShapes(aShape1, anIndices);
1372 Handle(TColStd_HArray1OfInteger) anArray;
1374 TopTools_IndexedMapOfShape mapShape1;
1375 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1377 Handle(GEOM_Object) anObj;
1378 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1379 TCollection_AsciiString anAsciiList, anEntry;
1381 TopTools_MapOfShape mapShape2;
1382 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1383 for (; exp.More(); exp.Next()) {
1384 TopoDS_Shape aSS = exp.Current();
1385 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1386 anArray = new TColStd_HArray1OfInteger(1,1);
1387 anArray->SetValue(1, anIndices.FindIndex(aSS));
1388 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1389 aSeq->Append(anObj);
1391 // for python command
1392 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1393 anAsciiList += anEntry;
1398 if (aSeq->IsEmpty()) {
1399 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1403 //Make a Python command
1404 anAsciiList.Trunc(anAsciiList.Length() - 1);
1406 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1408 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1409 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1410 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1416 //=============================================================================
1420 //=============================================================================
1421 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1422 const GEOMAlgo_State theState)
1425 case GEOMAlgo_ST_IN:
1426 theDump << "geompy.GEOM.ST_IN";
1428 case GEOMAlgo_ST_OUT:
1429 theDump << "geompy.GEOM.ST_OUT";
1431 case GEOMAlgo_ST_ON:
1432 theDump << "geompy.GEOM.ST_ON";
1434 case GEOMAlgo_ST_ONIN:
1435 theDump << "geompy.GEOM.ST_ONIN";
1437 case GEOMAlgo_ST_ONOUT:
1438 theDump << "geompy.GEOM.ST_ONOUT";
1441 theDump << "geompy.GEOM.ST_UNKNOWN";
1447 //=======================================================================
1448 //function : checkTypeShapesOn
1450 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1451 * \param theShapeType - the shape type to check
1452 * \retval bool - result of the check
1454 //=======================================================================
1455 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1457 if (theShapeType != TopAbs_VERTEX &&
1458 theShapeType != TopAbs_EDGE &&
1459 theShapeType != TopAbs_FACE &&
1460 theShapeType != TopAbs_SOLID) {
1461 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1467 //=======================================================================
1468 //function : makePlane
1470 * \brief Creates Geom_Plane
1471 * \param theAx1 - shape object defining plane parameters
1472 * \retval Handle(Geom_Surface) - resulting surface
1474 //=======================================================================
1475 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1477 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1478 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1479 TopoDS_Vertex V1, V2;
1480 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1481 if (V1.IsNull() || V2.IsNull()) {
1482 SetErrorCode("Bad edge given for the plane normal vector");
1485 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1486 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1487 if (aVec.Magnitude() < Precision::Confusion()) {
1488 SetErrorCode("Vector with null magnitude given");
1491 return new Geom_Plane(aLoc, aVec);
1494 //=======================================================================
1495 //function : makeCylinder
1497 * \brief Creates Geom_CylindricalSurface
1498 * \param theAx1 - edge defining cylinder axis
1499 * \param theRadius - cylinder radius
1500 * \retval Handle(Geom_Surface) - resulting surface
1502 //=======================================================================
1503 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1504 const Standard_Real theRadius)
1506 //Axis of the cylinder
1507 if (anAxis.ShapeType() != TopAbs_EDGE) {
1508 SetErrorCode("Not an edge given for the axis");
1511 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1512 TopoDS_Vertex V1, V2;
1513 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1514 if (V1.IsNull() || V2.IsNull()) {
1515 SetErrorCode("Bad edge given for the axis");
1518 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1519 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1520 if (aVec.Magnitude() < Precision::Confusion()) {
1521 SetErrorCode("Vector with null magnitude given");
1525 gp_Ax3 anAx3 (aLoc, aVec);
1526 return new Geom_CylindricalSurface(anAx3, theRadius);
1529 //=======================================================================
1530 //function : getShapesOnBoxIDs
1532 * \brief Find IDs of subshapes complying with given status about surface
1533 * \param theBox - the box to check state of subshapes against
1534 * \param theShape - the shape to explore
1535 * \param theShapeType - type of subshape of theShape
1536 * \param theState - required state
1537 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1539 //=======================================================================
1540 Handle(TColStd_HSequenceOfInteger)
1541 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1542 const Handle(GEOM_Object)& theShape,
1543 const Standard_Integer theShapeType,
1544 GEOMAlgo_State theState)
1546 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1548 TopoDS_Shape aBox = theBox->GetValue();
1549 TopoDS_Shape aShape = theShape->GetValue();
1551 // Check presence of triangulation, build if need
1552 if (!CheckTriangulation(aShape)) {
1553 SetErrorCode("Cannot build triangulation on the shape");
1558 GEOMAlgo_FinderShapeOn2 aFinder;
1559 Standard_Real aTol = 0.0001; // default value
1561 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1562 aClsfBox->SetBox(aBox);
1564 aFinder.SetShape(aShape);
1565 aFinder.SetTolerance(aTol);
1566 aFinder.SetClsf(aClsfBox);
1567 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1568 aFinder.SetState(theState);
1571 // Interprete results
1572 Standard_Integer iErr = aFinder.ErrorStatus();
1573 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1575 MESSAGE(" iErr : " << iErr);
1576 TCollection_AsciiString aMsg (" iErr : ");
1577 aMsg += TCollection_AsciiString(iErr);
1581 Standard_Integer iWrn = aFinder.WarningStatus();
1582 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1584 MESSAGE(" *** iWrn : " << iWrn);
1587 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1589 if (listSS.Extent() < 1) {
1590 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1591 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1595 // Fill sequence of object IDs
1596 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1598 TopTools_IndexedMapOfShape anIndices;
1599 TopExp::MapShapes(aShape, anIndices);
1601 TopTools_ListIteratorOfListOfShape itSub (listSS);
1602 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1603 int id = anIndices.FindIndex(itSub.Value());
1604 aSeqOfIDs->Append(id);
1610 //=======================================================================
1611 //function : GetShapesOnBoxIDs
1613 * \brief Find subshapes complying with given status about surface
1614 * \param theBox - the box to check state of subshapes against
1615 * \param theShape - the shape to explore
1616 * \param theShapeType - type of subshape of theShape
1617 * \param theState - required state
1618 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1620 //=======================================================================
1621 Handle(TColStd_HSequenceOfInteger)
1622 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1623 const Handle(GEOM_Object)& theShape,
1624 const Standard_Integer theShapeType,
1625 GEOMAlgo_State theState)
1627 // Find subshapes ids
1628 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1629 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1630 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1633 // The GetShapesOnBox() doesn't change object so no new function is required.
1634 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1636 // Make a Python command
1637 GEOM::TPythonDump(aFunction)
1638 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1641 << TopAbs_ShapeEnum(theShapeType) << ", "
1648 //=======================================================================
1649 //function : GetShapesOnBox
1651 * \brief Find subshapes complying with given status about surface
1652 * \param theBox - the box to check state of subshapes against
1653 * \param theShape - the shape to explore
1654 * \param theShapeType - type of subshape of theShape
1655 * \param theState - required state
1656 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1658 //=======================================================================
1659 Handle(TColStd_HSequenceOfTransient)
1660 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1661 const Handle(GEOM_Object)& theShape,
1662 const Standard_Integer theShapeType,
1663 GEOMAlgo_State theState)
1665 // Find subshapes ids
1666 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1667 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1668 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1671 // Find objects by indices
1672 TCollection_AsciiString anAsciiList;
1673 Handle(TColStd_HSequenceOfTransient) aSeq;
1674 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1675 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1678 // Make a Python command
1680 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1681 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1683 GEOM::TPythonDump(aFunction)
1684 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1687 << TopAbs_ShapeEnum(theShapeType) << ", "
1694 //=======================================================================
1695 //function : getShapesOnShapeIDs
1697 * \brief Find IDs of subshapes complying with given status about surface
1698 * \param theCheckShape - the shape to check state of subshapes against
1699 * \param theShape - the shape to explore
1700 * \param theShapeType - type of subshape of theShape
1701 * \param theState - required state
1702 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1704 //=======================================================================
1705 Handle(TColStd_HSequenceOfInteger)
1706 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1707 (const Handle(GEOM_Object)& theCheckShape,
1708 const Handle(GEOM_Object)& theShape,
1709 const Standard_Integer theShapeType,
1710 GEOMAlgo_State theState)
1712 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1714 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
1715 TopoDS_Shape aShape = theShape->GetValue();
1716 TopTools_ListOfShape res;
1718 // Check presence of triangulation, build if need
1719 if (!CheckTriangulation(aShape)) {
1720 SetErrorCode("Cannot build triangulation on the shape");
1725 GEOMAlgo_FinderShapeOn2 aFinder;
1726 Standard_Real aTol = 0.0001; // default value
1728 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
1729 aClsfSolid->SetShape(aCheckShape);
1731 aFinder.SetShape(aShape);
1732 aFinder.SetTolerance(aTol);
1733 aFinder.SetClsf(aClsfSolid);
1734 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1735 aFinder.SetState(theState);
1738 // Interprete results
1739 Standard_Integer iErr = aFinder.ErrorStatus();
1740 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1743 SetErrorCode("theCheckShape must be a solid");
1746 MESSAGE(" iErr : " << iErr);
1747 TCollection_AsciiString aMsg (" iErr : ");
1748 aMsg += TCollection_AsciiString(iErr);
1753 Standard_Integer iWrn = aFinder.WarningStatus();
1754 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1756 MESSAGE(" *** iWrn : " << iWrn);
1759 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1761 if (listSS.Extent() < 1) {
1762 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1763 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1766 // Fill sequence of object IDs
1767 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1769 TopTools_IndexedMapOfShape anIndices;
1770 TopExp::MapShapes(aShape, anIndices);
1772 TopTools_ListIteratorOfListOfShape itSub (listSS);
1773 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1774 int id = anIndices.FindIndex(itSub.Value());
1775 aSeqOfIDs->Append(id);
1781 //=======================================================================
1782 //function : GetShapesOnShapeIDs
1784 * \brief Find subshapes complying with given status about surface
1785 * \param theCheckShape - the shape to check state of subshapes against
1786 * \param theShape - the shape to explore
1787 * \param theShapeType - type of subshape of theShape
1788 * \param theState - required state
1789 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1791 //=======================================================================
1792 Handle(TColStd_HSequenceOfInteger)
1793 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
1794 (const Handle(GEOM_Object)& theCheckShape,
1795 const Handle(GEOM_Object)& theShape,
1796 const Standard_Integer theShapeType,
1797 GEOMAlgo_State theState)
1799 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1800 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1802 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1805 // The GetShapesOnShape() doesn't change object so no new function is required.
1806 Handle(GEOM_Function) aFunction =
1807 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
1809 // Make a Python command
1810 GEOM::TPythonDump(aFunction)
1811 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
1812 << theCheckShape << ", "
1814 << TopAbs_ShapeEnum(theShapeType) << ", "
1821 //=======================================================================
1822 //function : GetShapesOnShape
1824 * \brief Find subshapes complying with given status about surface
1825 * \param theCheckShape - the shape to check state of subshapes against
1826 * \param theShape - the shape to explore
1827 * \param theShapeType - type of subshape of theShape
1828 * \param theState - required state
1829 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1831 //=======================================================================
1832 Handle(TColStd_HSequenceOfTransient)
1833 GEOMImpl_IShapesOperations::GetShapesOnShape
1834 (const Handle(GEOM_Object)& theCheckShape,
1835 const Handle(GEOM_Object)& theShape,
1836 const Standard_Integer theShapeType,
1837 GEOMAlgo_State theState)
1839 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1840 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1841 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1844 // Find objects by indices
1845 TCollection_AsciiString anAsciiList;
1846 Handle(TColStd_HSequenceOfTransient) aSeq;
1847 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1849 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1852 // Make a Python command
1854 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1855 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1857 GEOM::TPythonDump(aFunction)
1858 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
1859 << theCheckShape << ", "
1861 << TopAbs_ShapeEnum(theShapeType) << ", "
1868 //=======================================================================
1869 //function : GetShapesOnShapeAsCompound
1870 //=======================================================================
1871 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
1872 (const Handle(GEOM_Object)& theCheckShape,
1873 const Handle(GEOM_Object)& theShape,
1874 const Standard_Integer theShapeType,
1875 GEOMAlgo_State theState)
1877 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1878 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1880 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1883 // Find objects by indices
1884 TCollection_AsciiString anAsciiList;
1885 Handle(TColStd_HSequenceOfTransient) aSeq;
1886 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1888 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1891 TopoDS_Compound aCompound;
1893 B.MakeCompound(aCompound);
1895 for(; i<=aSeq->Length(); i++) {
1896 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
1897 TopoDS_Shape aShape_i = anObj->GetValue();
1898 B.Add(aCompound,aShape_i);
1901 //Add a new result object
1902 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
1903 Handle(GEOM_Function) aFunction =
1904 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
1905 aFunction->SetValue(aCompound);
1907 GEOM::TPythonDump(aFunction)
1908 << aRes << " = geompy.GetShapesOnShapeAsCompound("
1909 << theCheckShape << ", "
1911 << TopAbs_ShapeEnum(theShapeType) << ", "
1919 //=======================================================================
1920 //function : getShapesOnSurfaceIDs
1922 * \brief Find IDs of subshapes complying with given status about surface
1923 * \param theSurface - the surface to check state of subshapes against
1924 * \param theShape - the shape to explore
1925 * \param theShapeType - type of subshape of theShape
1926 * \param theState - required state
1927 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1929 //=======================================================================
1930 Handle(TColStd_HSequenceOfInteger)
1931 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1932 const TopoDS_Shape& theShape,
1933 TopAbs_ShapeEnum theShapeType,
1934 GEOMAlgo_State theState)
1936 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1938 // Check presence of triangulation, build if need
1939 if (!CheckTriangulation(theShape)) {
1940 SetErrorCode("Cannot build triangulation on the shape");
1945 GEOMAlgo_FinderShapeOn1 aFinder;
1946 Standard_Real aTol = 0.0001; // default value
1948 aFinder.SetShape(theShape);
1949 aFinder.SetTolerance(aTol);
1950 aFinder.SetSurface(theSurface);
1951 aFinder.SetShapeType(theShapeType);
1952 aFinder.SetState(theState);
1954 // Sets the minimal number of inner points for the faces that do not have own
1955 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1957 aFinder.SetNbPntsMin(3);
1958 // Sets the maximal number of inner points for edges or faces.
1959 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1960 // the performance. If this value =0, all inner points will be taken into account.
1962 aFinder.SetNbPntsMax(100);
1966 // Interprete results
1967 Standard_Integer iErr = aFinder.ErrorStatus();
1968 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1970 MESSAGE(" iErr : " << iErr);
1971 TCollection_AsciiString aMsg (" iErr : ");
1972 aMsg += TCollection_AsciiString(iErr);
1976 Standard_Integer iWrn = aFinder.WarningStatus();
1977 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1979 MESSAGE(" *** iWrn : " << iWrn);
1982 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1984 if (listSS.Extent() < 1) {
1985 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1986 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1990 // Fill sequence of object IDs
1991 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1993 TopTools_IndexedMapOfShape anIndices;
1994 TopExp::MapShapes(theShape, anIndices);
1996 TopTools_ListIteratorOfListOfShape itSub (listSS);
1997 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1998 int id = anIndices.FindIndex(itSub.Value());
1999 aSeqOfIDs->Append(id);
2005 //=======================================================================
2006 //function : getObjectsShapesOn
2008 * \brief Find shape objects and their entries by their ids
2009 * \param theShapeIDs - incoming shape ids
2010 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2011 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2013 //=======================================================================
2014 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2015 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2016 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2017 TCollection_AsciiString & theShapeEntries)
2019 Handle(TColStd_HSequenceOfTransient) aSeq;
2021 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2023 aSeq = new TColStd_HSequenceOfTransient;
2024 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2025 TCollection_AsciiString anEntry;
2026 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2028 anArray->SetValue(1, theShapeIDs->Value( i ));
2029 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2030 aSeq->Append( anObj );
2032 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2033 if ( i != 1 ) theShapeEntries += ",";
2034 theShapeEntries += anEntry;
2040 //=======================================================================
2041 //function : getShapesOnSurface
2043 * \brief Find subshapes complying with given status about surface
2044 * \param theSurface - the surface to check state of subshapes against
2045 * \param theShape - the shape to explore
2046 * \param theShapeType - type of subshape of theShape
2047 * \param theState - required state
2048 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2049 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2051 //=======================================================================
2052 Handle(TColStd_HSequenceOfTransient)
2053 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2054 const Handle(GEOM_Object)& theShape,
2055 TopAbs_ShapeEnum theShapeType,
2056 GEOMAlgo_State theState,
2057 TCollection_AsciiString & theShapeEntries)
2059 // Find subshapes ids
2060 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2061 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2062 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2065 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2068 //=============================================================================
2072 //=============================================================================
2073 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2074 (const Handle(GEOM_Object)& theShape,
2075 const Standard_Integer theShapeType,
2076 const Handle(GEOM_Object)& theAx1,
2077 const GEOMAlgo_State theState)
2081 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2083 TopoDS_Shape aShape = theShape->GetValue();
2084 TopoDS_Shape anAx1 = theAx1->GetValue();
2086 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2088 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2089 if ( !checkTypeShapesOn( theShapeType ))
2093 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2094 if ( aPlane.IsNull() )
2098 TCollection_AsciiString anAsciiList;
2099 Handle(TColStd_HSequenceOfTransient) aSeq;
2100 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2101 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2104 // Make a Python command
2106 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2107 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2109 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2110 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2111 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2117 //=============================================================================
2119 * GetShapesOnPlaneWithLocation
2121 //=============================================================================
2122 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2123 (const Handle(GEOM_Object)& theShape,
2124 const Standard_Integer theShapeType,
2125 const Handle(GEOM_Object)& theAx1,
2126 const Handle(GEOM_Object)& thePnt,
2127 const GEOMAlgo_State theState)
2131 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2133 TopoDS_Shape aShape = theShape->GetValue();
2134 TopoDS_Shape anAx1 = theAx1->GetValue();
2135 TopoDS_Shape anPnt = thePnt->GetValue();
2137 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2139 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2140 if ( !checkTypeShapesOn( theShapeType ))
2144 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2145 TopoDS_Vertex V1, V2, V3;
2146 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2147 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2149 if (V1.IsNull() || V2.IsNull()) {
2150 SetErrorCode("Bad edge given for the plane normal vector");
2153 V3 = TopoDS::Vertex(anPnt);
2156 SetErrorCode("Bad vertex given for the plane location");
2159 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2160 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2162 if (aVec.Magnitude() < Precision::Confusion()) {
2163 SetErrorCode("Vector with null magnitude given");
2166 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2168 if ( aPlane.IsNull() )
2172 TCollection_AsciiString anAsciiList;
2173 Handle(TColStd_HSequenceOfTransient) aSeq;
2174 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2175 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2178 // Make a Python command
2180 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2181 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2183 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2184 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2185 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2191 //=============================================================================
2193 * GetShapesOnCylinder
2195 //=============================================================================
2196 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2197 (const Handle(GEOM_Object)& theShape,
2198 const Standard_Integer theShapeType,
2199 const Handle(GEOM_Object)& theAxis,
2200 const Standard_Real theRadius,
2201 const GEOMAlgo_State theState)
2205 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2207 TopoDS_Shape aShape = theShape->GetValue();
2208 TopoDS_Shape anAxis = theAxis->GetValue();
2210 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2212 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2213 if ( !checkTypeShapesOn( aShapeType ))
2216 // Create a cylinder surface
2217 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2218 if ( aCylinder.IsNull() )
2222 TCollection_AsciiString anAsciiList;
2223 Handle(TColStd_HSequenceOfTransient) aSeq;
2224 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2225 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2228 // Make a Python command
2230 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2231 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2233 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2234 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2235 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2241 //=============================================================================
2243 * GetShapesOnCylinderWithLocation
2245 //=============================================================================
2246 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2247 (const Handle(GEOM_Object)& theShape,
2248 const Standard_Integer theShapeType,
2249 const Handle(GEOM_Object)& theAxis,
2250 const Handle(GEOM_Object)& thePnt,
2251 const Standard_Real theRadius,
2252 const GEOMAlgo_State theState)
2256 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2258 TopoDS_Shape aShape = theShape->GetValue();
2259 TopoDS_Shape anAxis = theAxis->GetValue();
2260 TopoDS_Shape aPnt = thePnt->GetValue();
2262 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2264 if (aPnt.ShapeType() != TopAbs_VERTEX )
2266 SetErrorCode("Bottom location point must be vertex");
2270 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2271 if ( !checkTypeShapesOn( aShapeType ))
2274 // Create a cylinder surface
2275 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2276 if ( aCylinder.IsNull() )
2279 // translate the surface
2280 Handle(Geom_CylindricalSurface) aCylSurface =
2281 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2282 if ( aCylSurface.IsNull() )
2284 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2287 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2288 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2289 aCylinder->Translate( fromLoc, toLoc );
2292 TCollection_AsciiString anAsciiList;
2293 Handle(TColStd_HSequenceOfTransient) aSeq;
2294 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2295 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2298 // Make a Python command
2300 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2301 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2303 GEOM::TPythonDump(aFunction)
2304 << "[" << anAsciiList.ToCString()
2305 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
2306 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
2312 //=============================================================================
2316 //=============================================================================
2317 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2318 (const Handle(GEOM_Object)& theShape,
2319 const Standard_Integer theShapeType,
2320 const Handle(GEOM_Object)& theCenter,
2321 const Standard_Real theRadius,
2322 const GEOMAlgo_State theState)
2326 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2328 TopoDS_Shape aShape = theShape->GetValue();
2329 TopoDS_Shape aCenter = theCenter->GetValue();
2331 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2333 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2334 if ( !checkTypeShapesOn( aShapeType ))
2337 // Center of the sphere
2338 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2339 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2341 gp_Ax3 anAx3 (aLoc, gp::DZ());
2342 Handle(Geom_SphericalSurface) aSphere =
2343 new Geom_SphericalSurface(anAx3, theRadius);
2346 TCollection_AsciiString anAsciiList;
2347 Handle(TColStd_HSequenceOfTransient) aSeq;
2348 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2349 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2352 // Make a Python command
2354 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2355 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2357 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2358 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2359 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2365 //=============================================================================
2367 * GetShapesOnPlaneIDs
2369 //=============================================================================
2370 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2371 (const Handle(GEOM_Object)& theShape,
2372 const Standard_Integer theShapeType,
2373 const Handle(GEOM_Object)& theAx1,
2374 const GEOMAlgo_State theState)
2378 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2380 TopoDS_Shape aShape = theShape->GetValue();
2381 TopoDS_Shape anAx1 = theAx1->GetValue();
2383 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2385 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2386 if ( !checkTypeShapesOn( aShapeType ))
2390 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2391 if ( aPlane.IsNull() )
2395 Handle(TColStd_HSequenceOfInteger) aSeq;
2396 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2398 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2399 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2401 // Make a Python command
2402 GEOM::TPythonDump(aFunction, /*append=*/true)
2403 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2404 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2410 //=============================================================================
2412 * GetShapesOnPlaneWithLocationIDs
2414 //=============================================================================
2415 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2416 (const Handle(GEOM_Object)& theShape,
2417 const Standard_Integer theShapeType,
2418 const Handle(GEOM_Object)& theAx1,
2419 const Handle(GEOM_Object)& thePnt,
2420 const GEOMAlgo_State theState)
2424 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2426 TopoDS_Shape aShape = theShape->GetValue();
2427 TopoDS_Shape anAx1 = theAx1->GetValue();
2428 TopoDS_Shape anPnt = thePnt->GetValue();
2430 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2432 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2433 if ( !checkTypeShapesOn( aShapeType ))
2437 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2438 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2439 TopoDS_Vertex V1, V2, V3;
2440 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2441 if (V1.IsNull() || V2.IsNull()) {
2442 SetErrorCode("Bad edge given for the plane normal vector");
2445 V3 = TopoDS::Vertex(anPnt);
2447 SetErrorCode("Bad vertex given for the plane location");
2450 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2451 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2452 if (aVec.Magnitude() < Precision::Confusion()) {
2453 SetErrorCode("Vector with null magnitude given");
2457 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2458 if ( aPlane.IsNull() )
2462 Handle(TColStd_HSequenceOfInteger) aSeq;
2463 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2465 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2466 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2468 // Make a Python command
2469 GEOM::TPythonDump(aFunction, /*append=*/true)
2470 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2471 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2477 //=============================================================================
2479 * GetShapesOnCylinderIDs
2481 //=============================================================================
2482 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2483 (const Handle(GEOM_Object)& theShape,
2484 const Standard_Integer theShapeType,
2485 const Handle(GEOM_Object)& theAxis,
2486 const Standard_Real theRadius,
2487 const GEOMAlgo_State theState)
2491 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2493 TopoDS_Shape aShape = theShape->GetValue();
2494 TopoDS_Shape anAxis = theAxis->GetValue();
2496 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2498 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2499 if ( !checkTypeShapesOn( aShapeType ))
2502 // Create a cylinder surface
2503 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2504 if ( aCylinder.IsNull() )
2508 Handle(TColStd_HSequenceOfInteger) aSeq;
2509 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2511 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2512 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2514 // Make a Python command
2515 GEOM::TPythonDump(aFunction, /*append=*/true)
2516 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2517 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2518 << theRadius << ", " << theState << ")";
2524 //=============================================================================
2526 * GetShapesOnCylinderWithLocationIDs
2528 //=============================================================================
2529 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
2530 (const Handle(GEOM_Object)& theShape,
2531 const Standard_Integer theShapeType,
2532 const Handle(GEOM_Object)& theAxis,
2533 const Handle(GEOM_Object)& thePnt,
2534 const Standard_Real theRadius,
2535 const GEOMAlgo_State theState)
2539 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2541 TopoDS_Shape aShape = theShape->GetValue();
2542 TopoDS_Shape anAxis = theAxis->GetValue();
2543 TopoDS_Shape aPnt = thePnt->GetValue();
2545 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2547 if (aPnt.ShapeType() != TopAbs_VERTEX )
2549 SetErrorCode("Bottom location point must be vertex");
2553 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2554 if ( !checkTypeShapesOn( aShapeType ))
2557 // Create a cylinder surface
2558 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2559 if ( aCylinder.IsNull() )
2562 // translate the surface
2563 Handle(Geom_CylindricalSurface) aCylSurface =
2564 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2565 if ( aCylSurface.IsNull() )
2567 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2570 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2571 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2572 aCylinder->Translate( fromLoc, toLoc );
2575 Handle(TColStd_HSequenceOfInteger) aSeq;
2576 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2578 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2579 Handle(GEOM_Function) aFunction =
2580 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
2582 // Make a Python command
2583 GEOM::TPythonDump(aFunction, /*append=*/true)
2584 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
2585 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2586 << thePnt << ", " << theRadius << ", " << theState << ")";
2592 //=============================================================================
2594 * GetShapesOnSphereIDs
2596 //=============================================================================
2597 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2598 (const Handle(GEOM_Object)& theShape,
2599 const Standard_Integer theShapeType,
2600 const Handle(GEOM_Object)& theCenter,
2601 const Standard_Real theRadius,
2602 const GEOMAlgo_State theState)
2606 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2608 TopoDS_Shape aShape = theShape->GetValue();
2609 TopoDS_Shape aCenter = theCenter->GetValue();
2611 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2613 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2614 if ( !checkTypeShapesOn( aShapeType ))
2617 // Center of the sphere
2618 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2619 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2621 gp_Ax3 anAx3 (aLoc, gp::DZ());
2622 Handle(Geom_SphericalSurface) aSphere =
2623 new Geom_SphericalSurface(anAx3, theRadius);
2626 Handle(TColStd_HSequenceOfInteger) aSeq;
2627 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2629 // The GetShapesOnSphere() doesn't change object so no new function is required.
2630 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2632 // Make a Python command
2633 GEOM::TPythonDump(aFunction, /*append=*/true)
2634 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2635 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2636 << theRadius << ", " << theState << ")";
2642 //=======================================================================
2643 //function : getShapesOnQuadrangleIDs
2645 * \brief Find IDs of subshapes complying with given status about quadrangle
2646 * \param theShape - the shape to explore
2647 * \param theShapeType - type of subshape of theShape
2648 * \param theTopLeftPoint - top left quadrangle corner
2649 * \param theTopRigthPoint - top right quadrangle corner
2650 * \param theBottomLeftPoint - bottom left quadrangle corner
2651 * \param theBottomRigthPoint - bottom right quadrangle corner
2652 * \param theState - required state
2653 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2655 //=======================================================================
2656 Handle(TColStd_HSequenceOfInteger)
2657 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2658 const Standard_Integer theShapeType,
2659 const Handle(GEOM_Object)& theTopLeftPoint,
2660 const Handle(GEOM_Object)& theTopRigthPoint,
2661 const Handle(GEOM_Object)& theBottomLeftPoint,
2662 const Handle(GEOM_Object)& theBottomRigthPoint,
2663 const GEOMAlgo_State theState)
2667 if ( theShape.IsNull() ||
2668 theTopLeftPoint.IsNull() ||
2669 theTopRigthPoint.IsNull() ||
2670 theBottomLeftPoint.IsNull() ||
2671 theBottomRigthPoint.IsNull() )
2674 TopoDS_Shape aShape = theShape->GetValue();
2675 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2676 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2677 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2678 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2680 if (aShape.IsNull() ||
2685 aTL.ShapeType() != TopAbs_VERTEX ||
2686 aTR.ShapeType() != TopAbs_VERTEX ||
2687 aBL.ShapeType() != TopAbs_VERTEX ||
2688 aBR.ShapeType() != TopAbs_VERTEX )
2691 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2692 if ( !checkTypeShapesOn( aShapeType ))
2695 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2697 // Check presence of triangulation, build if need
2698 if (!CheckTriangulation(aShape)) {
2699 SetErrorCode("Cannot build triangulation on the shape");
2704 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2705 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2706 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2707 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2709 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2710 Standard_Real aTol = 0.0001; // default value
2712 aFinder.SetShape(aShape);
2713 aFinder.SetTolerance(aTol);
2714 //aFinder.SetSurface(theSurface);
2715 aFinder.SetShapeType(aShapeType);
2716 aFinder.SetState(theState);
2718 // Sets the minimal number of inner points for the faces that do not have own
2719 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2721 aFinder.SetNbPntsMin(3);
2722 // Sets the maximal number of inner points for edges or faces.
2723 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2724 // the performance. If this value =0, all inner points will be taken into account.
2726 aFinder.SetNbPntsMax(100);
2730 // Interprete results
2731 Standard_Integer iErr = aFinder.ErrorStatus();
2732 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2734 MESSAGE(" iErr : " << iErr);
2735 TCollection_AsciiString aMsg (" iErr : ");
2736 aMsg += TCollection_AsciiString(iErr);
2740 Standard_Integer iWrn = aFinder.WarningStatus();
2741 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2743 MESSAGE(" *** iWrn : " << iWrn);
2746 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2748 if (listSS.Extent() < 1) {
2749 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2750 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2754 // Fill sequence of object IDs
2755 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2757 TopTools_IndexedMapOfShape anIndices;
2758 TopExp::MapShapes(aShape, anIndices);
2760 TopTools_ListIteratorOfListOfShape itSub (listSS);
2761 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2762 int id = anIndices.FindIndex(itSub.Value());
2763 aSeqOfIDs->Append(id);
2768 //=======================================================================
2769 //function : GetShapesOnQuadrangle
2771 * \brief Find subshapes complying with given status about quadrangle
2772 * \param theShape - the shape to explore
2773 * \param theShapeType - type of subshape of theShape
2774 * \param theTopLeftPoint - top left quadrangle corner
2775 * \param theTopRigthPoint - top right quadrangle corner
2776 * \param theBottomLeftPoint - bottom left quadrangle corner
2777 * \param theBottomRigthPoint - bottom right quadrangle corner
2778 * \param theState - required state
2779 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2781 //=======================================================================
2782 Handle(TColStd_HSequenceOfTransient)
2783 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2784 const Standard_Integer theShapeType,
2785 const Handle(GEOM_Object)& theTopLeftPoint,
2786 const Handle(GEOM_Object)& theTopRigthPoint,
2787 const Handle(GEOM_Object)& theBottomLeftPoint,
2788 const Handle(GEOM_Object)& theBottomRigthPoint,
2789 const GEOMAlgo_State theState)
2792 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2793 getShapesOnQuadrangleIDs( theShape,
2798 theBottomRigthPoint,
2800 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2803 // Find objects by indices
2804 TCollection_AsciiString anAsciiList;
2805 Handle(TColStd_HSequenceOfTransient) aSeq;
2806 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2807 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2810 // Make a Python command
2812 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2813 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2815 GEOM::TPythonDump(aFunction)
2816 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2818 << TopAbs_ShapeEnum(theShapeType) << ", "
2819 << theTopLeftPoint << ", "
2820 << theTopRigthPoint << ", "
2821 << theBottomLeftPoint << ", "
2822 << theBottomRigthPoint << ", "
2829 //=======================================================================
2830 //function : GetShapesOnQuadrangleIDs
2832 * \brief Find IDs of subshapes complying with given status about quadrangle
2833 * \param theShape - the shape to explore
2834 * \param theShapeType - type of subshape of theShape
2835 * \param theTopLeftPoint - top left quadrangle corner
2836 * \param theTopRigthPoint - top right quadrangle corner
2837 * \param theBottomLeftPoint - bottom left quadrangle corner
2838 * \param theBottomRigthPoint - bottom right quadrangle corner
2839 * \param theState - required state
2840 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2842 //=======================================================================
2843 Handle(TColStd_HSequenceOfInteger)
2844 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2845 const Standard_Integer theShapeType,
2846 const Handle(GEOM_Object)& theTopLeftPoint,
2847 const Handle(GEOM_Object)& theTopRigthPoint,
2848 const Handle(GEOM_Object)& theBottomLeftPoint,
2849 const Handle(GEOM_Object)& theBottomRigthPoint,
2850 const GEOMAlgo_State theState)
2853 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2854 getShapesOnQuadrangleIDs( theShape,
2859 theBottomRigthPoint,
2861 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2864 // Make a Python command
2866 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2867 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2868 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2869 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2870 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2871 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2873 GEOM::TPythonDump(aFunction, /*append=*/true)
2874 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2876 << TopAbs_ShapeEnum(theShapeType) << ", "
2877 << theTopLeftPoint << ", "
2878 << theTopRigthPoint << ", "
2879 << theBottomLeftPoint << ", "
2880 << theBottomRigthPoint << ", "
2887 //=============================================================================
2891 //=============================================================================
2892 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2893 const TopTools_IndexedMapOfShape& theWhereIndices,
2894 const TopoDS_Shape& theWhat,
2895 TColStd_ListOfInteger& theModifiedList)
2897 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2899 if (theWhereIndices.Contains(theWhat)) {
2900 // entity was not changed by the operation
2901 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2902 theModifiedList.Append(aWhatIndex);
2906 // try to find in history
2907 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2909 // search in history for all argument shapes
2910 Standard_Boolean isFound = Standard_False;
2911 Standard_Boolean isGood = Standard_False;
2913 TDF_LabelSequence aLabelSeq;
2914 theWhereFunction->GetDependency(aLabelSeq);
2915 Standard_Integer nbArg = aLabelSeq.Length();
2917 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2919 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2921 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2922 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2924 TopTools_IndexedMapOfShape anArgumentIndices;
2925 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2927 if (anArgumentIndices.Contains(theWhat)) {
2928 isFound = Standard_True;
2929 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2931 // Find corresponding label in history
2932 TDF_Label anArgumentHistoryLabel =
2933 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2934 if (anArgumentHistoryLabel.IsNull()) {
2935 // Lost History of operation argument. Possibly, all its entities was removed.
2936 isGood = Standard_True;
2939 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2941 if (aWhatHistoryLabel.IsNull()) {
2942 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2943 isGood = Standard_False;
2945 Handle(TDataStd_IntegerArray) anIntegerArray;
2946 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2947 //Error: Empty modifications history for the sought shape.
2948 isGood = Standard_False;
2951 isGood = Standard_True;
2952 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2953 for (imod = 1; imod <= aModifLen; imod++) {
2954 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2965 // try compound/compsolid/shell/wire element by element
2966 bool isFoundAny = false;
2967 TopTools_MapOfShape mapShape;
2969 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2970 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2971 // recursive processing of compound/compsolid
2972 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2973 for (; anIt.More(); anIt.Next()) {
2974 if (mapShape.Add(anIt.Value())) {
2975 TopoDS_Shape curWhat = anIt.Value();
2976 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2977 if (isFoundAny) isFound = Standard_True;
2981 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2982 // try to replace a shell by its faces images
2983 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2984 for (; anExp.More(); anExp.Next()) {
2985 if (mapShape.Add(anExp.Current())) {
2986 TopoDS_Shape curWhat = anExp.Current();
2987 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2988 if (isFoundAny) isFound = Standard_True;
2992 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2993 // try to replace a wire by its edges images
2994 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2995 for (; anExp.More(); anExp.Next()) {
2996 if (mapShape.Add(anExp.Current())) {
2997 TopoDS_Shape curWhat = anExp.Current();
2998 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2999 if (isFoundAny) isFound = Standard_True;
3011 //=============================================================================
3013 * GetShapeProperties
3015 //=============================================================================
3016 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3019 GProp_GProps theProps;
3021 //TopoDS_Shape aPntShape;
3022 Standard_Real aShapeSize;
3024 if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3025 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3026 else BRepGProp::VolumeProperties(aShape, theProps);
3028 aCenterMass = theProps.CentreOfMass();
3029 aShapeSize = theProps.Mass();
3031 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3032 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3033 aVertex = aCenterMass;
3034 tab[0] = aVertex.X();
3035 tab[1] = aVertex.Y();
3036 tab[2] = aVertex.Z();
3037 tab[3] = aShapeSize;
3043 //================================================================================
3045 * \brief Return normal to face at extrema point
3047 //================================================================================
3049 gp_Vec GetNormal(const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3051 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3053 // get UV at extrema point
3054 Standard_Real u,v, f,l;
3055 switch ( extrema.SupportTypeShape2(1) ) {
3056 case BRepExtrema_IsInFace: {
3057 extrema.ParOnFaceS2(1, u, v );
3060 case BRepExtrema_IsOnEdge: {
3061 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3062 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3063 extrema.ParOnEdgeS2( 1, u );
3064 gp_Pnt2d uv = pcurve->Value( u );
3069 case BRepExtrema_IsVertex: return defaultNorm;
3072 BRepAdaptor_Surface surface( face, false );
3073 gp_Vec du, dv; gp_Pnt p;
3074 surface.D1( u, v, p, du, dv );
3078 } catch (Standard_Failure ) {
3084 //=============================================================================
3089 //=============================================================================
3090 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3091 Handle(GEOM_Object) theShapeWhat)
3095 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3097 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3098 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3099 TopoDS_Shape aPntShape;
3100 TopoDS_Vertex aVertex;
3102 if (aWhere.IsNull() || aWhat.IsNull()) {
3103 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3107 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3108 if (aWhereFunction.IsNull()) {
3109 SetErrorCode("Error: aWhereFunction is Null.");
3113 TopTools_IndexedMapOfShape aWhereIndices;
3114 TopExp::MapShapes(aWhere, aWhereIndices);
3116 TColStd_ListOfInteger aModifiedList;
3117 Standard_Integer aWhereIndex;
3118 Handle(TColStd_HArray1OfInteger) aModifiedArray;
3119 Handle(GEOM_Object) aResult;
3121 bool isFound = false;
3122 Standard_Integer iType = TopAbs_SOLID;
3123 Standard_Integer compType = TopAbs_SOLID;
3124 Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
3125 Standard_Real tab_aWhat[4], tab_aWhere[4];
3126 Standard_Real dl_l = 1e-3;
3127 Standard_Real min_l, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3128 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3129 Bnd_Box BoundingBox;
3130 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3131 GProp_GProps aProps;
3133 // Find the iType of the aWhat shape
3134 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3135 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
3136 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
3137 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
3138 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
3139 // Only the iType of the first shape in the compound is taken into account
3140 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
3142 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
3145 compType = It.Value().ShapeType();
3146 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3147 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
3148 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
3149 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
3152 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3156 TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
3157 TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
3158 TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
3160 // Find the shortest edge in theShapeWhere shape
3161 BRepBndLib::Add(aWhere, BoundingBox);
3162 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3163 min_l = fabs(aXmax - aXmin);
3164 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3165 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3167 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3168 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3169 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3170 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3171 tab_Pnt[nbVertex] = aPnt;
3173 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3174 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3175 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3179 // Compute tolerances
3180 Tol_1D = dl_l * min_l;
3181 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3182 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3184 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3185 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3186 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3188 //if (Tol_1D > 1.0) Tol_1D = 1.0;
3189 //if (Tol_2D > 1.0) Tol_2D = 1.0;
3190 //if (Tol_3D > 1.0) Tol_3D = 1.0;
3193 if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3194 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3196 // Compute the ShapeWhat Mass
3197 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
3198 if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
3199 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
3200 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
3201 aWhat_Mass += aProps.Mass();
3204 // Searching for the sub-shapes inside the ShapeWhere shape
3205 TopTools_MapOfShape map_aWhere;
3206 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
3207 if (!map_aWhere.Add(Exp_aWhere.Current()))
3208 continue; // skip repeated shape to avoid mass addition
3209 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
3210 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
3211 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
3212 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
3215 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
3216 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
3217 aVertex = TopoDS::Vertex( aPntShape );
3218 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
3219 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
3220 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
3221 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
3223 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
3224 // aVertex must be projected to the same point on Where and on What
3225 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
3226 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
3227 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
3228 if ( isFound && iType == TopAbs_FACE )
3230 // check normals at pOnWhat and pOnWhere
3231 const double angleTol = PI/180.;
3232 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
3233 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
3234 if ( normToWhat * normToWhere < 0 )
3235 normToWhat.Reverse();
3236 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
3242 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
3243 aModifiedList.Append(aWhereIndex);
3244 aWhere_Mass += tab_aWhere[3];
3249 if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) break;
3252 if (aModifiedList.Extent() == 0) { // Not found any Results
3253 SetErrorCode(NOT_FOUND_ANY);
3257 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3258 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3259 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
3260 aModifiedArray->SetValue(imod, anIterModif.Value());
3263 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3264 if (aResult.IsNull()) {
3265 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3269 if (aModifiedArray->Length() > 1) {
3271 aResult->SetType(GEOM_GROUP);
3273 //Set a sub shape type
3274 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3275 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3277 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3278 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3281 //Make a Python command
3282 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3284 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3285 << theShapeWhere << ", " << theShapeWhat << ")";
3291 //=======================================================================
3292 //function : GetInPlaceByHistory
3294 //=======================================================================
3295 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
3296 (Handle(GEOM_Object) theShapeWhere,
3297 Handle(GEOM_Object) theShapeWhat)
3301 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3303 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3304 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3306 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3308 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3309 if (aWhereFunction.IsNull()) return NULL;
3311 //Fill array of indices
3312 TopTools_IndexedMapOfShape aWhereIndices;
3313 TopExp::MapShapes(aWhere, aWhereIndices);
3316 TColStd_ListOfInteger aModifiedList;
3317 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3319 if (!isFound || aModifiedList.Extent() < 1) {
3320 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3324 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3325 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3326 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3327 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3328 aModifiedArray->SetValue(imod, anIterModif.Value());
3332 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3333 if (aResult.IsNull()) {
3334 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3338 if (aModifiedArray->Length() > 1) {
3340 aResult->SetType(GEOM_GROUP);
3342 //Set a sub shape type
3343 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3344 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3346 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3347 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3350 //Make a Python command
3351 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3353 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
3354 << theShapeWhere << ", " << theShapeWhat << ")";
3360 //=======================================================================
3361 //function : SortShapes
3363 //=======================================================================
3364 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
3366 Standard_Integer MaxShapes = SL.Extent();
3367 TopTools_Array1OfShape aShapes (1,MaxShapes);
3368 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3369 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3370 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3372 // Computing of CentreOfMass
3373 Standard_Integer Index;
3376 TopTools_ListIteratorOfListOfShape it(SL);
3377 for (Index=1; it.More(); Index++)
3379 TopoDS_Shape S = it.Value();
3380 SL.Remove( it ); // == it.Next()
3382 OrderInd.SetValue (Index, Index);
3383 if (S.ShapeType() == TopAbs_VERTEX)
3385 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3386 Length.SetValue( Index, (Standard_Real) S.Orientation());
3390 BRepGProp::LinearProperties (S, GPr);
3391 GPoint = GPr.CentreOfMass();
3392 Length.SetValue( Index, GPr.Mass() );
3394 MidXYZ.SetValue(Index,
3395 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3396 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3400 Standard_Integer aTemp;
3401 Standard_Boolean exchange, Sort = Standard_True;
3402 Standard_Real tol = Precision::Confusion();
3405 Sort = Standard_False;
3406 for (Index=1; Index < MaxShapes; Index++)
3408 exchange = Standard_False;
3409 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3410 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3411 if ( dMidXYZ >= tol ) {
3412 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3413 // << " d: " << dMidXYZ << endl;
3414 exchange = Standard_True;
3416 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3417 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3418 // << " d: " << dLength << endl;
3419 exchange = Standard_True;
3421 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3422 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3424 // equal values possible on shapes such as two halves of a sphere and
3425 // a membrane inside the sphere
3427 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3428 if ( box1.IsVoid() ) continue;
3429 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3430 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3431 if ( dSquareExtent >= tol ) {
3432 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3433 exchange = Standard_True;
3435 else if ( Abs(dSquareExtent) < tol ) {
3436 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3437 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3438 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3439 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3440 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3441 //exchange = val1 > val2;
3442 if ((val1 - val2) >= tol) {
3443 exchange = Standard_True;
3445 //cout << "box: " << val1<<" > "<<val2 << endl;
3451 // cout << "exchange " << Index << " & " << Index+1 << endl;
3452 aTemp = OrderInd(Index);
3453 OrderInd(Index) = OrderInd(Index+1);
3454 OrderInd(Index+1) = aTemp;
3455 Sort = Standard_True;
3460 for (Index=1; Index <= MaxShapes; Index++)
3461 SL.Append( aShapes( OrderInd(Index) ));
3464 //=======================================================================
3465 //function : CompsolidToCompound
3467 //=======================================================================
3468 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3470 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3471 return theCompsolid;
3474 TopoDS_Compound aCompound;
3476 B.MakeCompound(aCompound);
3478 TopTools_MapOfShape mapShape;
3479 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3481 for (; It.More(); It.Next()) {
3482 TopoDS_Shape aShape_i = It.Value();
3483 if (mapShape.Add(aShape_i)) {
3484 B.Add(aCompound, aShape_i);
3491 //=======================================================================
3492 //function : CheckTriangulation
3494 //=======================================================================
3495 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3497 bool isTriangulation = true;
3499 TopExp_Explorer exp (aShape, TopAbs_FACE);
3502 TopLoc_Location aTopLoc;
3503 Handle(Poly_Triangulation) aTRF;
3504 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3505 if (aTRF.IsNull()) {
3506 isTriangulation = false;
3509 else // no faces, try edges
3511 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3515 TopLoc_Location aLoc;
3516 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3518 isTriangulation = false;
3522 if (!isTriangulation) {
3523 // calculate deflection
3524 Standard_Real aDeviationCoefficient = 0.001;
3527 BRepBndLib::Add(aShape, B);
3528 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3529 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3531 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3532 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3533 Standard_Real aHLRAngle = 0.349066;
3535 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3541 #define MAX_TOLERANCE 1.e-7
3543 //=======================================================================
3544 //function : isSameEdge
3545 //purpose : Returns True if two edges coincide
3546 //=======================================================================
3547 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3549 TopoDS_Vertex V11, V12, V21, V22;
3550 TopExp::Vertices(theEdge1, V11, V12);
3551 TopExp::Vertices(theEdge2, V21, V22);
3552 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3553 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3554 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3555 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3556 bool coincide = false;
3558 //Check that ends of edges coincide
3559 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3560 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3562 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3563 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3566 if(!coincide) return false;
3568 if (BRep_Tool::Degenerated(theEdge1))
3569 if (BRep_Tool::Degenerated(theEdge2)) return true;
3572 if (BRep_Tool::Degenerated(theEdge2)) return false;
3574 double U11, U12, U21, U22;
3575 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3576 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3577 if(C1->DynamicType() == C2->DynamicType()) return true;
3579 //Check that both edges has the same geometry
3580 double range = U12-U11;
3581 double U = U11+ range/3.0;
3582 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3583 U = U11+range*2.0/3.0;
3584 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3586 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3589 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3591 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3594 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3599 #include <TopoDS_TShape.hxx>
3600 //=======================================================================
3601 //function : isSameFace
3602 //purpose : Returns True if two faces coincide
3603 //=======================================================================
3604 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3606 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3607 TopTools_ListOfShape LS1, LS2;
3608 for(; E.More(); E.Next()) LS1.Append(E.Current());
3610 E.Init(theFace2, TopAbs_EDGE);
3611 for(; E.More(); E.Next()) LS2.Append(E.Current());
3613 //Compare the number of edges in the faces
3614 if(LS1.Extent() != LS2.Extent()) return false;
3616 double aMin = RealFirst(), aMax = RealLast();
3617 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3618 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3620 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3621 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3622 if(P.X() < xminB1) xminB1 = P.X();
3623 if(P.Y() < yminB1) yminB1 = P.Y();
3624 if(P.Z() < zminB1) zminB1 = P.Z();
3625 if(P.X() > xmaxB1) xmaxB1 = P.X();
3626 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3627 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3630 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3631 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3632 if(P.X() < xminB2) xminB2 = P.X();
3633 if(P.Y() < yminB2) yminB2 = P.Y();
3634 if(P.Z() < zminB2) zminB2 = P.Z();
3635 if(P.X() > xmaxB2) xmaxB2 = P.X();
3636 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3637 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3640 //Compare the bounding boxes of both faces
3641 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3644 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3647 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3648 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3650 //Check if there a coincidence of two surfaces at least in two points
3651 double U11, U12, V11, V12, U21, U22, V21, V22;
3652 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3653 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3655 double rangeU = U12-U11;
3656 double rangeV = V12-V11;
3657 double U = U11 + rangeU/3.0;
3658 double V = V11 + rangeV/3.0;
3659 gp_Pnt P1 = S1->Value(U, V);
3660 U = U11+rangeU*2.0/3.0;
3661 V = V11+rangeV*2.0/3.0;
3662 gp_Pnt P2 = S1->Value(U, V);
3664 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3667 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3669 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3672 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3674 //Check that each edge of the Face1 has a counterpart in the Face2
3675 TopTools_MapOfOrientedShape aMap;
3676 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3677 for(; LSI1.More(); LSI1.Next()) {
3678 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3679 bool isFound = false;
3680 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3681 for(; LSI2.More(); LSI2.Next()) {
3682 TopoDS_Shape aValue = LSI2.Value();
3683 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3684 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3690 if(!isFound) return false;
3696 //=======================================================================
3697 //function : isSameSolid
3698 //purpose : Returns True if two solids coincide
3699 //=======================================================================
3700 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3702 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3703 TopTools_ListOfShape LS1, LS2;
3704 for(; E.More(); E.Next()) LS1.Append(E.Current());
3705 E.Init(theSolid2, TopAbs_FACE);
3706 for(; E.More(); E.Next()) LS2.Append(E.Current());
3708 if(LS1.Extent() != LS2.Extent()) return false;
3710 double aMin = RealFirst(), aMax = RealLast();
3711 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3712 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3714 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3715 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3716 if(P.X() < xminB1) xminB1 = P.X();
3717 if(P.Y() < yminB1) yminB1 = P.Y();
3718 if(P.Z() < zminB1) zminB1 = P.Z();
3719 if(P.X() > xmaxB1) xmaxB1 = P.X();
3720 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3721 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3724 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
3725 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3726 if(P.X() < xminB2) xminB2 = P.X();
3727 if(P.Y() < yminB2) yminB2 = P.Y();
3728 if(P.Z() < zminB2) zminB2 = P.Z();
3729 if(P.X() > xmaxB2) xmaxB2 = P.X();
3730 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3731 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3734 //Compare the bounding boxes of both solids
3735 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3738 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3741 //Check that each face of the Solid1 has a counterpart in the Solid2
3742 TopTools_MapOfOrientedShape aMap;
3743 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3744 for(; LSI1.More(); LSI1.Next()) {
3745 TopoDS_Face F = TopoDS::Face(LSI1.Value());
3746 bool isFound = false;
3747 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3748 for(; LSI2.More(); LSI2.Next()) {
3749 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
3750 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
3751 aMap.Add(LSI2.Value());
3756 if(!isFound) return false;
3762 //=======================================================================
3763 //function : GetSame
3765 //=======================================================================
3766 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
3767 const Handle(GEOM_Object)& theShapeWhat)
3770 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3772 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3773 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3775 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3778 bool isFound = false;
3779 TopoDS_Shape aSubShape;
3780 TopTools_MapOfShape aMap;
3782 switch(aWhat.ShapeType()) {
3783 case TopAbs_VERTEX: {
3784 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
3785 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
3786 for(; E.More(); E.Next()) {
3787 if(!aMap.Add(E.Current())) continue;
3788 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3789 if(P.Distance(P2) <= MAX_TOLERANCE) {
3791 aSubShape = E.Current();
3798 TopoDS_Face aFace = TopoDS::Face(aWhat);
3799 TopExp_Explorer E(aWhere, TopAbs_FACE);
3800 for(; E.More(); E.Next()) {
3801 if(!aMap.Add(E.Current())) continue;
3802 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
3803 aSubShape = E.Current();
3811 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3812 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3813 for(; E.More(); E.Next()) {
3814 if(!aMap.Add(E.Current())) continue;
3815 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3816 aSubShape = E.Current();
3823 case TopAbs_SOLID: {
3824 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3825 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3826 for(; E.More(); E.Next()) {
3827 if(!aMap.Add(E.Current())) continue;
3828 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3829 aSubShape = E.Current();
3841 TopTools_IndexedMapOfShape anIndices;
3842 TopExp::MapShapes(aWhere, anIndices);
3843 if (anIndices.Contains(aSubShape))
3844 anIndex = anIndices.FindIndex(aSubShape);
3847 if(anIndex < 0) return NULL;
3849 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3851 anArray->SetValue(1, anIndex);
3853 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3854 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3856 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3857 << theShapeWhere << ", " << theShapeWhat << ")";