1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : GEOMImpl_IShapesOperations.cxx
24 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
28 #include <Standard_Stream.hxx>
30 #include "GEOMImpl_IShapesOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
34 #include "GEOMImpl_VectorDriver.hxx"
35 #include "GEOMImpl_ShapeDriver.hxx"
36 #include "GEOMImpl_CopyDriver.hxx"
37 #include "GEOMImpl_GlueDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_Block6Explorer.hxx"
45 #include "GEOM_Function.hxx"
46 #include "GEOM_ISubShape.hxx"
47 #include "GEOM_PythonDump.hxx"
49 #include "GEOMAlgo_FinderShapeOn1.hxx"
50 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
51 #include "GEOMAlgo_FinderShapeOn2.hxx"
52 #include "GEOMAlgo_ClsfBox.hxx"
53 #include "GEOMAlgo_ClsfSolid.hxx"
54 #include "GEOMAlgo_Gluer1.hxx"
55 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
56 #include "GEOMAlgo_CoupleOfShapes.hxx"
57 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
59 #include "utilities.h"
61 #include "Utils_ExceptHandlers.hxx"
63 #include <TFunction_DriverTable.hxx>
64 #include <TFunction_Driver.hxx>
65 #include <TFunction_Logbook.hxx>
66 #include <TDataStd_Integer.hxx>
67 #include <TDataStd_IntegerArray.hxx>
68 #include <TDF_Tool.hxx>
70 #include <BRepExtrema_ExtCF.hxx>
71 #include <BRepExtrema_DistShapeShape.hxx>
73 #include <BRep_Tool.hxx>
74 #include <BRep_Builder.hxx>
75 #include <BRepTools.hxx>
76 #include <BRepGProp.hxx>
77 #include <BRepAdaptor_Curve.hxx>
78 #include <BRepAdaptor_Surface.hxx>
79 #include <BRepBndLib.hxx>
80 #include <BRepBuilderAPI_MakeFace.hxx>
81 #include <BRepMesh_IncrementalMesh.hxx>
86 #include <TopoDS_Shape.hxx>
87 #include <TopoDS_Solid.hxx>
88 #include <TopoDS_Face.hxx>
89 #include <TopoDS_Edge.hxx>
90 #include <TopoDS_Vertex.hxx>
91 #include <TopoDS_Compound.hxx>
92 #include <TopoDS_Iterator.hxx>
93 #include <TopExp_Explorer.hxx>
94 #include <TopLoc_Location.hxx>
95 #include <TopTools_MapOfShape.hxx>
96 #include <TopTools_MapOfOrientedShape.hxx>
97 #include <TopTools_Array1OfShape.hxx>
98 #include <TopTools_ListIteratorOfListOfShape.hxx>
99 #include <TopTools_IndexedMapOfShape.hxx>
101 #include <Geom_Surface.hxx>
102 #include <Geom_Plane.hxx>
103 #include <Geom_SphericalSurface.hxx>
104 #include <Geom_CylindricalSurface.hxx>
105 #include <GeomAdaptor_Surface.hxx>
107 #include <GeomLib_Tool.hxx>
108 #include <Geom2d_Curve.hxx>
110 #include <Bnd_Box.hxx>
111 #include <GProp_GProps.hxx>
112 #include <gp_Pnt.hxx>
113 #include <gp_Lin.hxx>
114 #include <TColStd_ListOfInteger.hxx>
115 #include <TColStd_ListIteratorOfListOfInteger.hxx>
116 #include <TColStd_Array1OfReal.hxx>
117 #include <TColStd_HArray1OfInteger.hxx>
121 #include <Standard_NullObject.hxx>
122 #include <Standard_Failure.hxx>
123 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
125 // Includes added for GetInPlace algorithm improvement
127 #include <GEOMImpl_MeasureDriver.hxx>
128 #include <GEOMImpl_IMeasure.hxx>
129 #include <BRepBuilderAPI_MakeVertex.hxx>
131 #include <BRepClass_FaceClassifier.hxx>
132 #include <BRepClass3d_SolidClassifier.hxx>
133 #include <Precision.hxx>
135 //=============================================================================
139 //=============================================================================
140 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
141 : GEOM_IOperations(theEngine, theDocID)
143 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
146 //=============================================================================
150 //=============================================================================
151 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
153 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
156 //=============================================================================
160 //=============================================================================
161 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
162 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
166 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
168 //Add a new Edge object
169 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
171 //Add a new Vector function
172 Handle(GEOM_Function) aFunction =
173 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
175 //Check if the function is set correctly
176 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
178 GEOMImpl_IVector aPI (aFunction);
180 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
181 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
182 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
184 aPI.SetPoint1(aRef1);
185 aPI.SetPoint2(aRef2);
187 //Compute the Edge value
189 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
192 if (!GetSolver()->ComputeFunction(aFunction)) {
193 SetErrorCode("Vector driver failed");
197 catch (Standard_Failure) {
198 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
199 SetErrorCode(aFail->GetMessageString());
203 //Make a Python command
204 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
205 << thePnt1 << ", " << thePnt2 << ")";
211 //=============================================================================
215 //=============================================================================
216 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
217 (std::list<Handle(GEOM_Object)> theShapes,
218 const Standard_Real theTolerance)
223 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
226 Handle(GEOM_Function) aFunction =
227 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
228 if (aFunction.IsNull()) return NULL;
230 //Check if the function is set correctly
231 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
233 GEOMImpl_IShapes aCI (aFunction);
234 aCI.SetTolerance(theTolerance);
236 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
239 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
240 for (; it != theShapes.end(); it++) {
241 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
242 if (aRefSh.IsNull()) {
243 SetErrorCode("NULL argument shape for the shape construction");
246 aShapesSeq->Append(aRefSh);
248 aCI.SetShapes(aShapesSeq);
252 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
255 if (!GetSolver()->ComputeFunction(aFunction)) {
256 SetErrorCode("Shape driver failed");
260 catch (Standard_Failure) {
261 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
262 SetErrorCode(aFail->GetMessageString());
266 //Make a Python command
267 GEOM::TPythonDump pd (aFunction);
268 pd << aWire << " = geompy.MakeWire([";
271 it = theShapes.begin();
272 if (it != theShapes.end()) {
274 while (it != theShapes.end()) {
275 pd << ", " << (*it++);
284 //=============================================================================
288 //=============================================================================
289 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
290 const bool isPlanarWanted)
294 if (theWire.IsNull()) return NULL;
296 //Add a new Face object
297 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
299 //Add a new Shape function for creation of a face from a wire
300 Handle(GEOM_Function) aFunction =
301 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
302 if (aFunction.IsNull()) return NULL;
304 //Check if the function is set correctly
305 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
307 GEOMImpl_IShapes aCI (aFunction);
309 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
311 if (aRefWire.IsNull()) return NULL;
313 aCI.SetBase(aRefWire);
314 aCI.SetIsPlanar(isPlanarWanted);
316 //Compute the Face value
318 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
321 if (!GetSolver()->ComputeFunction(aFunction)) {
322 SetErrorCode("Shape driver failed to compute a face");
326 catch (Standard_Failure) {
327 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
328 SetErrorCode(aFail->GetMessageString());
332 //Make a Python command
333 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
334 << theWire << ", " << (int)isPlanarWanted << ")";
340 //=============================================================================
344 //=============================================================================
345 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
346 (std::list<Handle(GEOM_Object)> theShapes,
347 const bool isPlanarWanted)
352 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
355 Handle(GEOM_Function) aFunction =
356 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
357 if (aFunction.IsNull()) return NULL;
359 //Check if the function is set correctly
360 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
362 GEOMImpl_IShapes aCI (aFunction);
364 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
367 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
368 for (; it != theShapes.end(); it++) {
369 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
370 if (aRefSh.IsNull()) {
371 SetErrorCode("NULL argument shape for the face construction");
374 aShapesSeq->Append(aRefSh);
376 aCI.SetShapes(aShapesSeq);
378 aCI.SetIsPlanar(isPlanarWanted);
382 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
385 if (!GetSolver()->ComputeFunction(aFunction)) {
386 SetErrorCode("Shape driver failed");
390 catch (Standard_Failure) {
391 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
392 SetErrorCode(aFail->GetMessageString());
396 //Make a Python command
397 GEOM::TPythonDump pd (aFunction);
398 pd << aShape << " = geompy.MakeFaceWires([";
401 it = theShapes.begin();
402 if (it != theShapes.end()) {
404 while (it != theShapes.end()) {
405 pd << ", " << (*it++);
408 pd << "], " << (int)isPlanarWanted << ")";
414 //=============================================================================
418 //=============================================================================
419 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
420 (std::list<Handle(GEOM_Object)> theShapes)
422 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
425 //=============================================================================
429 //=============================================================================
430 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
431 (std::list<Handle(GEOM_Object)> theShapes)
433 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
436 //=============================================================================
440 //=============================================================================
441 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
445 if (theShell.IsNull()) return NULL;
447 //Add a new Solid object
448 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
450 //Add a new Solid function for creation of a solid from a shell
451 Handle(GEOM_Function) aFunction =
452 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
453 if (aFunction.IsNull()) return NULL;
455 //Check if the function is set correctly
456 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
458 GEOMImpl_IShapes aCI (aFunction);
460 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
462 if (aRefShell.IsNull()) return NULL;
464 aCI.SetBase(aRefShell);
466 //Compute the Solid value
468 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
471 if (!GetSolver()->ComputeFunction(aFunction)) {
472 SetErrorCode("Solid driver failed");
476 catch (Standard_Failure) {
477 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
478 SetErrorCode(aFail->GetMessageString());
482 //Make a Python command
483 GEOM::TPythonDump(aFunction) << aSolid
484 << " = geompy.MakeSolid(" << theShell << ")";
490 //=============================================================================
494 //=============================================================================
495 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
496 (std::list<Handle(GEOM_Object)> theShapes)
498 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
501 //=============================================================================
505 //=============================================================================
506 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
507 (std::list<Handle(GEOM_Object)> theShapes,
508 const Standard_Integer theObjectType,
509 const Standard_Integer theFunctionType,
510 const TCollection_AsciiString& theMethodName)
515 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
518 Handle(GEOM_Function) aFunction =
519 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
520 if (aFunction.IsNull()) return NULL;
522 //Check if the function is set correctly
523 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
525 GEOMImpl_IShapes aCI (aFunction);
527 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
530 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
531 for (; it != theShapes.end(); it++) {
532 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
533 if (aRefSh.IsNull()) {
534 SetErrorCode("NULL argument shape for the shape construction");
537 aShapesSeq->Append(aRefSh);
539 aCI.SetShapes(aShapesSeq);
543 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
546 if (!GetSolver()->ComputeFunction(aFunction)) {
547 SetErrorCode("Shape driver failed");
551 catch (Standard_Failure) {
552 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
553 SetErrorCode(aFail->GetMessageString());
557 //Make a Python command
558 GEOM::TPythonDump pd (aFunction);
559 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
562 it = theShapes.begin();
563 if (it != theShapes.end()) {
565 while (it != theShapes.end()) {
566 pd << ", " << (*it++);
575 //=============================================================================
579 //=============================================================================
580 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
581 (Handle(GEOM_Object) theShape,
582 const Standard_Real theTolerance,
583 const Standard_Boolean doKeepNonSolids)
587 if (theShape.IsNull()) return NULL;
589 //Add a new Glued object
590 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
592 //Add a new Glue function
593 Handle(GEOM_Function) aFunction;
594 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
595 if (aFunction.IsNull()) return NULL;
597 //Check if the function is set correctly
598 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
600 GEOMImpl_IGlue aCI (aFunction);
602 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
603 if (aRefShape.IsNull()) return NULL;
605 aCI.SetBase(aRefShape);
606 aCI.SetTolerance(theTolerance);
607 aCI.SetKeepNonSolids(doKeepNonSolids);
609 //Compute the sub-shape value
610 Standard_Boolean isWarning = Standard_False;
612 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
615 if (!GetSolver()->ComputeFunction(aFunction)) {
616 SetErrorCode("Shape driver failed to glue faces");
620 catch (Standard_Failure) {
621 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
622 SetErrorCode(aFail->GetMessageString());
623 // to provide warning
624 if (!aFunction->GetValue().IsNull()) {
625 isWarning = Standard_True;
631 //Make a Python command
632 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
633 << theShape << ", " << theTolerance << ")";
635 // to provide warning
636 if (!isWarning) SetErrorCode(OK);
640 //=============================================================================
644 //=============================================================================
645 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
646 (Handle(GEOM_Object) theShape,
647 const Standard_Real theTolerance)
651 if (theShape.IsNull()) return NULL;
652 TopoDS_Shape aShape = theShape->GetValue();
653 if (aShape.IsNull()) return NULL;
655 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
657 Standard_Integer iErr;
659 GEOMAlgo_Gluer1 aGluer;
660 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
661 GEOMAlgo_CoupleOfShapes aCS;
662 GEOMAlgo_ListOfCoupleOfShapes aLCS;
664 //aGluer = new GEOMAlgo_Gluer1;
665 aGluer.SetShape(aShape);
666 aGluer.SetTolerance(theTolerance);
668 iErr = aGluer.ErrorStatus();
669 if (iErr) return NULL;
671 TopTools_ListOfShape listShape;
672 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
674 aItCS.Initialize(aLCSG);
675 for (; aItCS.More(); aItCS.Next()) {
676 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
677 listShape.Append(aCSG.Shape1());
680 TopTools_ListIteratorOfListOfShape itSub (listShape);
681 TCollection_AsciiString anAsciiList, anEntry;
682 TopTools_IndexedMapOfShape anIndices;
683 TopExp::MapShapes(aShape, anIndices);
684 Handle(TColStd_HArray1OfInteger) anArray;
685 Handle(GEOM_Object) anObj;
686 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
687 TopoDS_Shape aValue = itSub.Value();
688 anArray = new TColStd_HArray1OfInteger(1,1);
689 anArray->SetValue(1, anIndices.FindIndex(aValue));
690 anObj = GetEngine()->AddSubShape(theShape, anArray);
691 if (!anObj.IsNull()) {
694 // for python command
695 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
696 anAsciiList += anEntry;
701 //Make a Python command
702 if(anAsciiList.Length()>0)
703 anAsciiList.Trunc(anAsciiList.Length() - 1);
704 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
705 GEOM::TPythonDump pd (aFunction, /*append=*/true);
706 pd << "[" << anAsciiList.ToCString();
707 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
714 //=============================================================================
716 * MakeGlueFacesByList
718 //=============================================================================
719 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
720 (Handle(GEOM_Object) theShape,
721 const Standard_Real theTolerance,
722 std::list<Handle(GEOM_Object)> theFaces,
723 const Standard_Boolean doKeepNonSolids)
727 if (theShape.IsNull()) return NULL;
729 //Add a new Glued object
730 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
732 //Add a new Glue function
733 Handle(GEOM_Function) aFunction;
734 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
735 if (aFunction.IsNull()) return NULL;
737 //Check if the function is set correctly
738 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
740 GEOMImpl_IGlue aCI (aFunction);
742 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
743 if (aRefShape.IsNull()) return NULL;
745 aCI.SetBase(aRefShape);
746 aCI.SetTolerance(theTolerance);
747 aCI.SetKeepNonSolids(doKeepNonSolids);
749 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
750 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
751 for (; it != theFaces.end(); it++) {
752 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
753 if (aRefSh.IsNull()) {
754 SetErrorCode("NULL argument shape for the shape construction");
757 aFaces->Append(aRefSh);
759 aCI.SetFaces(aFaces);
761 //Compute the sub-shape value
762 Standard_Boolean isWarning = Standard_False;
764 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
767 if (!GetSolver()->ComputeFunction(aFunction)) {
768 SetErrorCode("Shape driver failed to glue faces");
772 catch (Standard_Failure) {
773 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
774 SetErrorCode(aFail->GetMessageString());
775 // to provide warning
776 if (!aFunction->GetValue().IsNull()) {
777 isWarning = Standard_True;
783 //Make a Python command
785 GEOM::TPythonDump pd(aFunction);
786 pd << aGlued << " = geompy.MakeGlueFacesByList("
787 << theShape << ", " << theTolerance << ", [";
789 it = theFaces.begin();
790 if (it != theFaces.end()) {
792 while (it != theFaces.end()) {
793 pd << ", " << (*it++);
798 // to provide warning
799 if (!isWarning) SetErrorCode(OK);
803 //=============================================================================
807 //=============================================================================
808 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
809 (Handle(GEOM_Object) theShape,
810 const Standard_Integer theShapeType,
811 const Standard_Boolean isSorted)
815 if (theShape.IsNull()) return NULL;
816 TopoDS_Shape aShape = theShape->GetValue();
817 if (aShape.IsNull()) return NULL;
819 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
821 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
822 Handle(GEOM_Object) anObj;
823 TopTools_MapOfShape mapShape;
824 TopTools_ListOfShape listShape;
826 if (aShape.ShapeType() == TopAbs_COMPOUND &&
827 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
828 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
829 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
830 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
831 for (; It.More(); It.Next()) {
832 if (mapShape.Add(It.Value())) {
833 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
834 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
835 listShape.Append(It.Value());
840 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
841 for (; exp.More(); exp.Next())
842 if (mapShape.Add(exp.Current()))
843 listShape.Append(exp.Current());
846 if (listShape.IsEmpty()) {
847 //SetErrorCode("The given shape has no sub-shapes of the requested type");
848 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
853 SortShapes(listShape);
855 TopTools_IndexedMapOfShape anIndices;
856 TopExp::MapShapes(aShape, anIndices);
857 Handle(TColStd_HArray1OfInteger) anArray;
859 TopTools_ListIteratorOfListOfShape itSub (listShape);
860 TCollection_AsciiString anAsciiList, anEntry;
861 for (int index = 1; itSub.More(); itSub.Next(), ++index)
863 TopoDS_Shape aValue = itSub.Value();
864 anArray = new TColStd_HArray1OfInteger(1,1);
865 anArray->SetValue(1, anIndices.FindIndex(aValue));
867 //anObj = GetEngine()->AddSubShape(theShape, anArray);
869 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
870 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
871 if (aFunction.IsNull()) return aSeq;
873 GEOM_ISubShape aSSI (aFunction);
874 aSSI.SetMainShape(aMainShape);
875 aSSI.SetIndices(anArray);
877 // Set function value directly, as we know it.
878 // Usage of Solver here would lead to significant loss of time,
879 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
880 // on the main shape for each being calculated sub-shape separately.
881 aFunction->SetValue(aValue);
884 if (!anObj.IsNull()) {
887 // for python command
888 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
889 anAsciiList += anEntry;
894 //Make a Python command
895 anAsciiList.Trunc(anAsciiList.Length() - 1);
897 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
898 pd << "[" << anAsciiList.ToCString();
899 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
900 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
907 //=============================================================================
911 //=============================================================================
912 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
913 (Handle(GEOM_Object) theShape,
914 const Standard_Integer theShapeType,
915 const Standard_Boolean isSorted)
919 if (theShape.IsNull()) return NULL;
920 TopoDS_Shape aShape = theShape->GetValue();
921 if (aShape.IsNull()) return NULL;
923 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
924 TopTools_MapOfShape mapShape;
925 TopTools_ListOfShape listShape;
927 if (aShape.ShapeType() == TopAbs_COMPOUND &&
928 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
929 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
930 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
931 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
932 for (; It.More(); It.Next()) {
933 if (mapShape.Add(It.Value())) {
934 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
935 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
936 listShape.Append(It.Value());
941 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
942 for (; exp.More(); exp.Next())
943 if (!exp.Current().IsSame(aShape) && mapShape.Add(exp.Current()))
944 listShape.Append(exp.Current());
947 if (listShape.IsEmpty()) {
948 //SetErrorCode("The given shape has no sub-shapes of the requested type");
949 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
954 SortShapes(listShape);
956 TopTools_IndexedMapOfShape anIndices;
957 TopExp::MapShapes(aShape, anIndices);
958 Handle(TColStd_HArray1OfInteger) anArray;
960 TopTools_ListIteratorOfListOfShape itSub (listShape);
961 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
962 TopoDS_Shape aValue = itSub.Value();
963 aSeq->Append(anIndices.FindIndex(aValue));
966 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
968 //Make a Python command
969 GEOM::TPythonDump pd (aFunction, /*append=*/true);
970 pd << "listSubShapeIDs = geompy.SubShapeAll";
971 pd << (isSorted ? "SortedIDs(" : "IDs(");
972 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
978 //=============================================================================
982 //=============================================================================
983 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
984 (Handle(GEOM_Object) theMainShape,
985 const Standard_Integer theID)
989 if (theMainShape.IsNull()) return NULL;
991 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
992 anArray->SetValue(1, theID);
993 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
994 if (anObj.IsNull()) {
995 SetErrorCode("Can not get a sub-shape with the given ID");
999 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1001 //Make a Python command
1002 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1003 << theMainShape << ", [" << theID << "])";
1009 //=============================================================================
1013 //=============================================================================
1014 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1015 Handle(GEOM_Object) theSubShape)
1019 TopoDS_Shape aMainShape = theMainShape->GetValue();
1020 TopoDS_Shape aSubShape = theSubShape->GetValue();
1022 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1024 TopTools_IndexedMapOfShape anIndices;
1025 TopExp::MapShapes(aMainShape, anIndices);
1026 if (anIndices.Contains(aSubShape)) {
1028 return anIndices.FindIndex(aSubShape);
1034 //=============================================================================
1038 //=============================================================================
1039 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1040 Handle(GEOM_Object) theSubShape)
1044 TopoDS_Shape aMainShape = theMainShape->GetValue();
1045 TopoDS_Shape aSubShape = theSubShape->GetValue();
1047 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1048 SetErrorCode("Null argument shape given");
1053 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1055 TopTools_ListOfShape CL;
1056 CL.Append(aMainShape);
1057 TopTools_ListIteratorOfListOfShape itC;
1058 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1059 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1060 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1061 if (it.Value().IsSame(aSubShape))
1065 CL.Append(it.Value());
1070 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1071 TopTools_MapOfShape M;
1072 for (; anExp.More(); anExp.Next()) {
1073 if (M.Add(anExp.Current())) {
1074 if (anExp.Current().IsSame(aSubShape))
1081 SetErrorCode("The sub-shape does not belong to the main shape");
1085 //=============================================================================
1087 * GetShapeTypeString
1089 //=============================================================================
1090 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1094 TCollection_AsciiString aTypeName ("Null Shape");
1096 TopoDS_Shape aShape = theShape->GetValue();
1097 if (aShape.IsNull())
1100 switch (aShape.ShapeType() )
1102 case TopAbs_COMPOUND:
1103 aTypeName = "Compound";
1105 case TopAbs_COMPSOLID:
1106 aTypeName = "Compound Solid";
1109 aTypeName = "Solid";
1112 aTypeName = "Shell";
1116 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1117 if (surf.GetType() == GeomAbs_Plane)
1118 aTypeName = "Plane";
1119 else if (surf.GetType() == GeomAbs_Cylinder)
1120 aTypeName = "Cylindrical Face";
1121 else if (surf.GetType() == GeomAbs_Sphere)
1122 aTypeName = "Spherical Face";
1123 else if (surf.GetType() == GeomAbs_Torus)
1124 aTypeName = "Toroidal Face";
1125 else if (surf.GetType() == GeomAbs_Cone)
1126 aTypeName = "Conical Face";
1128 aTypeName = "GEOM::FACE";
1136 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1137 if (curv.GetType() == GeomAbs_Line) {
1138 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1139 (Abs(curv.LastParameter()) >= 1E6))
1143 } else if (curv.GetType() == GeomAbs_Circle) {
1144 if (curv.IsClosed())
1145 aTypeName = "Circle";
1154 aTypeName = "Vertex";
1157 aTypeName = "Shape";
1160 aTypeName = "Shape of unknown type";
1166 //=============================================================================
1170 //=============================================================================
1171 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1172 (Handle(GEOM_Object) theShape,
1173 const Standard_Integer theShapeType)
1176 Standard_Integer nbShapes = 0;
1178 if (theShape.IsNull()) return -1;
1179 TopoDS_Shape aShape = theShape->GetValue();
1180 if (aShape.IsNull()) return -1;
1183 TopTools_MapOfShape mapShape;
1185 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1186 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1187 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1188 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1189 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1190 for (; It.More(); It.Next()) {
1191 if (mapShape.Add(It.Value())) {
1192 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1193 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1199 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1200 for (; exp.More(); exp.Next())
1201 if (mapShape.Add(exp.Current()))
1207 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1210 int iType, nbTypes [TopAbs_SHAPE];
1211 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1213 nbTypes[aShape.ShapeType()]++;
1215 TopTools_MapOfShape aMapOfShape;
1216 aMapOfShape.Add(aShape);
1217 TopTools_ListOfShape aListOfShape;
1218 aListOfShape.Append(aShape);
1220 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1221 for (; itL.More(); itL.Next()) {
1222 TopoDS_Iterator it (itL.Value());
1223 for (; it.More(); it.Next()) {
1224 TopoDS_Shape s = it.Value();
1225 if (aMapOfShape.Add(s)) {
1226 aListOfShape.Append(s);
1227 nbTypes[s.ShapeType()]++;
1232 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1233 nbShapes = aMapOfShape.Extent();
1235 nbShapes = nbTypes[theShapeType];
1237 catch (Standard_Failure) {
1238 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1239 SetErrorCode(aFail->GetMessageString());
1247 //=============================================================================
1251 //=============================================================================
1252 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1256 if (theShape.IsNull()) return NULL;
1258 //Add a new reversed object
1259 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1261 //Add a new Revese function
1262 Handle(GEOM_Function) aFunction;
1263 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1264 if (aFunction.IsNull()) return NULL;
1266 //Check if the function is set correctly
1267 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1269 GEOMImpl_IShapes aSI (aFunction);
1271 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1272 if (aRefShape.IsNull()) return NULL;
1274 aSI.SetBase(aRefShape);
1276 //Compute the sub-shape value
1278 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1281 if (!GetSolver()->ComputeFunction(aFunction)) {
1282 SetErrorCode("Shape driver failed to reverse shape");
1286 catch (Standard_Failure) {
1287 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1288 SetErrorCode(aFail->GetMessageString());
1292 //Make a Python command
1293 GEOM::TPythonDump(aFunction) << aReversed
1294 << " = geompy.ChangeOrientation(" << theShape << ")";
1300 //=============================================================================
1304 //=============================================================================
1305 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1306 (Handle(GEOM_Object) theShape)
1310 if (theShape.IsNull()) return NULL;
1311 TopoDS_Shape aShape = theShape->GetValue();
1312 if (aShape.IsNull()) return NULL;
1314 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1316 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1317 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1318 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1320 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1323 SetErrorCode("The given shape has no faces");
1327 TopTools_IndexedMapOfShape anIndices;
1328 TopExp::MapShapes(aShape, anIndices);
1330 Standard_Integer id;
1331 for (; ind <= nbFaces; ind++) {
1332 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1333 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1338 //The explode doesn't change object so no new function is required.
1339 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1341 //Make a Python command
1342 GEOM::TPythonDump(aFunction, /*append=*/true)
1343 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1349 //=======================================================================
1350 //function : GetSharedShapes
1352 //=======================================================================
1353 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1354 (Handle(GEOM_Object) theShape1,
1355 Handle(GEOM_Object) theShape2,
1356 const Standard_Integer theShapeType)
1360 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1362 TopoDS_Shape aShape1 = theShape1->GetValue();
1363 TopoDS_Shape aShape2 = theShape2->GetValue();
1365 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1367 TopTools_IndexedMapOfShape anIndices;
1368 TopExp::MapShapes(aShape1, anIndices);
1369 Handle(TColStd_HArray1OfInteger) anArray;
1371 TopTools_IndexedMapOfShape mapShape1;
1372 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1374 Handle(GEOM_Object) anObj;
1375 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1376 TCollection_AsciiString anAsciiList, anEntry;
1378 TopTools_MapOfShape mapShape2;
1379 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1380 for (; exp.More(); exp.Next()) {
1381 TopoDS_Shape aSS = exp.Current();
1382 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1383 anArray = new TColStd_HArray1OfInteger(1,1);
1384 anArray->SetValue(1, anIndices.FindIndex(aSS));
1385 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1386 aSeq->Append(anObj);
1388 // for python command
1389 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1390 anAsciiList += anEntry;
1395 if (aSeq->IsEmpty()) {
1396 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1400 //Make a Python command
1401 anAsciiList.Trunc(anAsciiList.Length() - 1);
1403 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1405 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1406 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1407 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1413 //=============================================================================
1417 //=============================================================================
1418 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1419 const GEOMAlgo_State theState)
1422 case GEOMAlgo_ST_IN:
1423 theDump << "geompy.GEOM.ST_IN";
1425 case GEOMAlgo_ST_OUT:
1426 theDump << "geompy.GEOM.ST_OUT";
1428 case GEOMAlgo_ST_ON:
1429 theDump << "geompy.GEOM.ST_ON";
1431 case GEOMAlgo_ST_ONIN:
1432 theDump << "geompy.GEOM.ST_ONIN";
1434 case GEOMAlgo_ST_ONOUT:
1435 theDump << "geompy.GEOM.ST_ONOUT";
1438 theDump << "geompy.GEOM.ST_UNKNOWN";
1444 //=======================================================================
1445 //function : checkTypeShapesOn
1447 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1448 * \param theShapeType - the shape type to check
1449 * \retval bool - result of the check
1451 //=======================================================================
1452 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1454 if (theShapeType != TopAbs_VERTEX &&
1455 theShapeType != TopAbs_EDGE &&
1456 theShapeType != TopAbs_FACE &&
1457 theShapeType != TopAbs_SOLID) {
1458 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1464 //=======================================================================
1465 //function : makePlane
1467 * \brief Creates Geom_Plane
1468 * \param theAx1 - shape object defining plane parameters
1469 * \retval Handle(Geom_Surface) - resulting surface
1471 //=======================================================================
1472 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1474 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1475 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1476 TopoDS_Vertex V1, V2;
1477 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1478 if (V1.IsNull() || V2.IsNull()) {
1479 SetErrorCode("Bad edge given for the plane normal vector");
1482 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1483 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1484 if (aVec.Magnitude() < Precision::Confusion()) {
1485 SetErrorCode("Vector with null magnitude given");
1488 return new Geom_Plane(aLoc, aVec);
1491 //=======================================================================
1492 //function : makeCylinder
1494 * \brief Creates Geom_CylindricalSurface
1495 * \param theAx1 - edge defining cylinder axis
1496 * \param theRadius - cylinder radius
1497 * \retval Handle(Geom_Surface) - resulting surface
1499 //=======================================================================
1500 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1501 const Standard_Real theRadius)
1503 //Axis of the cylinder
1504 if (anAxis.ShapeType() != TopAbs_EDGE) {
1505 SetErrorCode("Not an edge given for the axis");
1508 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1509 TopoDS_Vertex V1, V2;
1510 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1511 if (V1.IsNull() || V2.IsNull()) {
1512 SetErrorCode("Bad edge given for the axis");
1515 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1516 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1517 if (aVec.Magnitude() < Precision::Confusion()) {
1518 SetErrorCode("Vector with null magnitude given");
1522 gp_Ax3 anAx3 (aLoc, aVec);
1523 return new Geom_CylindricalSurface(anAx3, theRadius);
1526 //=======================================================================
1527 //function : getShapesOnBoxIDs
1529 * \brief Find IDs of subshapes complying with given status about surface
1530 * \param theBox - the box to check state of subshapes against
1531 * \param theShape - the shape to explore
1532 * \param theShapeType - type of subshape of theShape
1533 * \param theState - required state
1534 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1536 //=======================================================================
1537 Handle(TColStd_HSequenceOfInteger)
1538 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1539 const Handle(GEOM_Object)& theShape,
1540 const Standard_Integer theShapeType,
1541 GEOMAlgo_State theState)
1543 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1545 TopoDS_Shape aBox = theBox->GetValue();
1546 TopoDS_Shape aShape = theShape->GetValue();
1548 // Check presence of triangulation, build if need
1549 if (!CheckTriangulation(aShape)) {
1550 SetErrorCode("Cannot build triangulation on the shape");
1555 GEOMAlgo_FinderShapeOn2 aFinder;
1556 Standard_Real aTol = 0.0001; // default value
1558 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1559 aClsfBox->SetBox(aBox);
1561 aFinder.SetShape(aShape);
1562 aFinder.SetTolerance(aTol);
1563 aFinder.SetClsf(aClsfBox);
1564 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1565 aFinder.SetState(theState);
1568 // Interprete results
1569 Standard_Integer iErr = aFinder.ErrorStatus();
1570 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1572 MESSAGE(" iErr : " << iErr);
1573 TCollection_AsciiString aMsg (" iErr : ");
1574 aMsg += TCollection_AsciiString(iErr);
1578 Standard_Integer iWrn = aFinder.WarningStatus();
1579 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1581 MESSAGE(" *** iWrn : " << iWrn);
1584 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1586 if (listSS.Extent() < 1) {
1587 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1588 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1592 // Fill sequence of object IDs
1593 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1595 TopTools_IndexedMapOfShape anIndices;
1596 TopExp::MapShapes(aShape, anIndices);
1598 TopTools_ListIteratorOfListOfShape itSub (listSS);
1599 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1600 int id = anIndices.FindIndex(itSub.Value());
1601 aSeqOfIDs->Append(id);
1607 //=======================================================================
1608 //function : GetShapesOnBoxIDs
1610 * \brief Find subshapes complying with given status about surface
1611 * \param theBox - the box to check state of subshapes against
1612 * \param theShape - the shape to explore
1613 * \param theShapeType - type of subshape of theShape
1614 * \param theState - required state
1615 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1617 //=======================================================================
1618 Handle(TColStd_HSequenceOfInteger)
1619 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1620 const Handle(GEOM_Object)& theShape,
1621 const Standard_Integer theShapeType,
1622 GEOMAlgo_State theState)
1624 // Find subshapes ids
1625 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1626 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1627 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1630 // The GetShapesOnBox() doesn't change object so no new function is required.
1631 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1633 // Make a Python command
1634 GEOM::TPythonDump(aFunction)
1635 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1638 << TopAbs_ShapeEnum(theShapeType) << ", "
1645 //=======================================================================
1646 //function : GetShapesOnBox
1648 * \brief Find subshapes complying with given status about surface
1649 * \param theBox - the box to check state of subshapes against
1650 * \param theShape - the shape to explore
1651 * \param theShapeType - type of subshape of theShape
1652 * \param theState - required state
1653 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1655 //=======================================================================
1656 Handle(TColStd_HSequenceOfTransient)
1657 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1658 const Handle(GEOM_Object)& theShape,
1659 const Standard_Integer theShapeType,
1660 GEOMAlgo_State theState)
1662 // Find subshapes ids
1663 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1664 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1665 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1668 // Find objects by indices
1669 TCollection_AsciiString anAsciiList;
1670 Handle(TColStd_HSequenceOfTransient) aSeq;
1671 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1672 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1675 // Make a Python command
1677 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1678 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1680 GEOM::TPythonDump(aFunction)
1681 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1684 << TopAbs_ShapeEnum(theShapeType) << ", "
1691 //=======================================================================
1692 //function : getShapesOnShapeIDs
1694 * \brief Find IDs of subshapes complying with given status about surface
1695 * \param theCheckShape - the shape to check state of subshapes against
1696 * \param theShape - the shape to explore
1697 * \param theShapeType - type of subshape of theShape
1698 * \param theState - required state
1699 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1701 //=======================================================================
1702 Handle(TColStd_HSequenceOfInteger)
1703 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1704 (const Handle(GEOM_Object)& theCheckShape,
1705 const Handle(GEOM_Object)& theShape,
1706 const Standard_Integer theShapeType,
1707 GEOMAlgo_State theState)
1709 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1711 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
1712 TopoDS_Shape aShape = theShape->GetValue();
1713 TopTools_ListOfShape res;
1715 // Check presence of triangulation, build if need
1716 if (!CheckTriangulation(aShape)) {
1717 SetErrorCode("Cannot build triangulation on the shape");
1722 GEOMAlgo_FinderShapeOn2 aFinder;
1723 Standard_Real aTol = 0.0001; // default value
1725 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
1726 aClsfSolid->SetShape(aCheckShape);
1728 aFinder.SetShape(aShape);
1729 aFinder.SetTolerance(aTol);
1730 aFinder.SetClsf(aClsfSolid);
1731 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1732 aFinder.SetState(theState);
1735 // Interprete results
1736 Standard_Integer iErr = aFinder.ErrorStatus();
1737 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1739 MESSAGE(" iErr : " << iErr);
1740 TCollection_AsciiString aMsg (" iErr : ");
1741 aMsg += TCollection_AsciiString(iErr);
1745 Standard_Integer iWrn = aFinder.WarningStatus();
1746 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1748 MESSAGE(" *** iWrn : " << iWrn);
1751 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1753 if (listSS.Extent() < 1) {
1754 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1755 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1758 // Fill sequence of object IDs
1759 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1761 TopTools_IndexedMapOfShape anIndices;
1762 TopExp::MapShapes(aShape, anIndices);
1764 TopTools_ListIteratorOfListOfShape itSub (listSS);
1765 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1766 int id = anIndices.FindIndex(itSub.Value());
1767 aSeqOfIDs->Append(id);
1773 //=======================================================================
1774 //function : GetShapesOnShapeIDs
1776 * \brief Find subshapes complying with given status about surface
1777 * \param theCheckShape - the shape to check state of subshapes against
1778 * \param theShape - the shape to explore
1779 * \param theShapeType - type of subshape of theShape
1780 * \param theState - required state
1781 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1783 //=======================================================================
1784 Handle(TColStd_HSequenceOfInteger)
1785 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
1786 (const Handle(GEOM_Object)& theCheckShape,
1787 const Handle(GEOM_Object)& theShape,
1788 const Standard_Integer theShapeType,
1789 GEOMAlgo_State theState)
1791 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1792 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1794 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1797 // The GetShapesOnShape() doesn't change object so no new function is required.
1798 Handle(GEOM_Function) aFunction =
1799 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
1801 // Make a Python command
1802 GEOM::TPythonDump(aFunction)
1803 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
1804 << theCheckShape << ", "
1806 << TopAbs_ShapeEnum(theShapeType) << ", "
1813 //=======================================================================
1814 //function : GetShapesOnShape
1816 * \brief Find subshapes complying with given status about surface
1817 * \param theCheckShape - the shape to check state of subshapes against
1818 * \param theShape - the shape to explore
1819 * \param theShapeType - type of subshape of theShape
1820 * \param theState - required state
1821 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1823 //=======================================================================
1824 Handle(TColStd_HSequenceOfTransient)
1825 GEOMImpl_IShapesOperations::GetShapesOnShape
1826 (const Handle(GEOM_Object)& theCheckShape,
1827 const Handle(GEOM_Object)& theShape,
1828 const Standard_Integer theShapeType,
1829 GEOMAlgo_State theState)
1831 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1832 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1833 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1836 // Find objects by indices
1837 TCollection_AsciiString anAsciiList;
1838 Handle(TColStd_HSequenceOfTransient) aSeq;
1839 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1841 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1844 // Make a Python command
1846 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1847 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1849 GEOM::TPythonDump(aFunction)
1850 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
1851 << theCheckShape << ", "
1853 << TopAbs_ShapeEnum(theShapeType) << ", "
1860 //=======================================================================
1861 //function : GetShapesOnShapeAsCompound
1862 //=======================================================================
1863 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
1864 (const Handle(GEOM_Object)& theCheckShape,
1865 const Handle(GEOM_Object)& theShape,
1866 const Standard_Integer theShapeType,
1867 GEOMAlgo_State theState)
1869 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1870 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1872 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1875 // Find objects by indices
1876 TCollection_AsciiString anAsciiList;
1877 Handle(TColStd_HSequenceOfTransient) aSeq;
1878 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1880 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1883 TopoDS_Compound aCompound;
1885 B.MakeCompound(aCompound);
1887 for(; i<=aSeq->Length(); i++) {
1888 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
1889 TopoDS_Shape aShape_i = anObj->GetValue();
1890 B.Add(aCompound,aShape_i);
1893 //Add a new result object
1894 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
1895 Handle(GEOM_Function) aFunction =
1896 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
1897 aFunction->SetValue(aCompound);
1899 GEOM::TPythonDump(aFunction)
1900 << aRes << " = geompy.GetShapesOnShapeAsCompound("
1901 << theCheckShape << ", "
1903 << TopAbs_ShapeEnum(theShapeType) << ", "
1911 //=======================================================================
1912 //function : getShapesOnSurfaceIDs
1914 * \brief Find IDs of subshapes complying with given status about surface
1915 * \param theSurface - the surface to check state of subshapes against
1916 * \param theShape - the shape to explore
1917 * \param theShapeType - type of subshape of theShape
1918 * \param theState - required state
1919 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1921 //=======================================================================
1922 Handle(TColStd_HSequenceOfInteger)
1923 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1924 const TopoDS_Shape& theShape,
1925 TopAbs_ShapeEnum theShapeType,
1926 GEOMAlgo_State theState)
1928 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1930 // Check presence of triangulation, build if need
1931 if (!CheckTriangulation(theShape)) {
1932 SetErrorCode("Cannot build triangulation on the shape");
1937 GEOMAlgo_FinderShapeOn1 aFinder;
1938 Standard_Real aTol = 0.0001; // default value
1940 aFinder.SetShape(theShape);
1941 aFinder.SetTolerance(aTol);
1942 aFinder.SetSurface(theSurface);
1943 aFinder.SetShapeType(theShapeType);
1944 aFinder.SetState(theState);
1946 // Sets the minimal number of inner points for the faces that do not have own
1947 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1949 aFinder.SetNbPntsMin(3);
1950 // Sets the maximal number of inner points for edges or faces.
1951 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1952 // the performance. If this value =0, all inner points will be taken into account.
1954 aFinder.SetNbPntsMax(100);
1958 // Interprete results
1959 Standard_Integer iErr = aFinder.ErrorStatus();
1960 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1962 MESSAGE(" iErr : " << iErr);
1963 TCollection_AsciiString aMsg (" iErr : ");
1964 aMsg += TCollection_AsciiString(iErr);
1968 Standard_Integer iWrn = aFinder.WarningStatus();
1969 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1971 MESSAGE(" *** iWrn : " << iWrn);
1974 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1976 if (listSS.Extent() < 1) {
1977 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1978 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1982 // Fill sequence of object IDs
1983 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1985 TopTools_IndexedMapOfShape anIndices;
1986 TopExp::MapShapes(theShape, anIndices);
1988 TopTools_ListIteratorOfListOfShape itSub (listSS);
1989 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1990 int id = anIndices.FindIndex(itSub.Value());
1991 aSeqOfIDs->Append(id);
1997 //=======================================================================
1998 //function : getObjectsShapesOn
2000 * \brief Find shape objects and their entries by their ids
2001 * \param theShapeIDs - incoming shape ids
2002 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2003 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2005 //=======================================================================
2006 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2007 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2008 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2009 TCollection_AsciiString & theShapeEntries)
2011 Handle(TColStd_HSequenceOfTransient) aSeq;
2013 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2015 aSeq = new TColStd_HSequenceOfTransient;
2016 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2017 TCollection_AsciiString anEntry;
2018 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2020 anArray->SetValue(1, theShapeIDs->Value( i ));
2021 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2022 aSeq->Append( anObj );
2024 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2025 if ( i != 1 ) theShapeEntries += ",";
2026 theShapeEntries += anEntry;
2032 //=======================================================================
2033 //function : getShapesOnSurface
2035 * \brief Find subshapes complying with given status about surface
2036 * \param theSurface - the surface to check state of subshapes against
2037 * \param theShape - the shape to explore
2038 * \param theShapeType - type of subshape of theShape
2039 * \param theState - required state
2040 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2041 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2043 //=======================================================================
2044 Handle(TColStd_HSequenceOfTransient)
2045 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2046 const Handle(GEOM_Object)& theShape,
2047 TopAbs_ShapeEnum theShapeType,
2048 GEOMAlgo_State theState,
2049 TCollection_AsciiString & theShapeEntries)
2051 // Find subshapes ids
2052 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2053 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2054 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2057 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2060 //=============================================================================
2064 //=============================================================================
2065 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2066 (const Handle(GEOM_Object)& theShape,
2067 const Standard_Integer theShapeType,
2068 const Handle(GEOM_Object)& theAx1,
2069 const GEOMAlgo_State theState)
2073 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2075 TopoDS_Shape aShape = theShape->GetValue();
2076 TopoDS_Shape anAx1 = theAx1->GetValue();
2078 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2080 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2081 if ( !checkTypeShapesOn( theShapeType ))
2085 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2086 if ( aPlane.IsNull() )
2090 TCollection_AsciiString anAsciiList;
2091 Handle(TColStd_HSequenceOfTransient) aSeq;
2092 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2093 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2096 // Make a Python command
2098 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2099 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2101 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2102 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2103 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2109 //=============================================================================
2111 * GetShapesOnPlaneWithLocation
2113 //=============================================================================
2114 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2115 (const Handle(GEOM_Object)& theShape,
2116 const Standard_Integer theShapeType,
2117 const Handle(GEOM_Object)& theAx1,
2118 const Handle(GEOM_Object)& thePnt,
2119 const GEOMAlgo_State theState)
2123 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2125 TopoDS_Shape aShape = theShape->GetValue();
2126 TopoDS_Shape anAx1 = theAx1->GetValue();
2127 TopoDS_Shape anPnt = thePnt->GetValue();
2129 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2131 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2132 if ( !checkTypeShapesOn( theShapeType ))
2136 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2137 TopoDS_Vertex V1, V2, V3;
2138 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2139 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2141 if (V1.IsNull() || V2.IsNull()) {
2142 SetErrorCode("Bad edge given for the plane normal vector");
2145 V3 = TopoDS::Vertex(anPnt);
2148 SetErrorCode("Bad vertex given for the plane location");
2151 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2152 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2154 if (aVec.Magnitude() < Precision::Confusion()) {
2155 SetErrorCode("Vector with null magnitude given");
2158 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2160 if ( aPlane.IsNull() )
2164 TCollection_AsciiString anAsciiList;
2165 Handle(TColStd_HSequenceOfTransient) aSeq;
2166 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2167 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2170 // Make a Python command
2172 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2173 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2175 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2176 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2177 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2183 //=============================================================================
2185 * GetShapesOnCylinder
2187 //=============================================================================
2188 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2189 (const Handle(GEOM_Object)& theShape,
2190 const Standard_Integer theShapeType,
2191 const Handle(GEOM_Object)& theAxis,
2192 const Standard_Real theRadius,
2193 const GEOMAlgo_State theState)
2197 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2199 TopoDS_Shape aShape = theShape->GetValue();
2200 TopoDS_Shape anAxis = theAxis->GetValue();
2202 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2204 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2205 if ( !checkTypeShapesOn( aShapeType ))
2208 // Create a cylinder surface
2209 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2210 if ( aCylinder.IsNull() )
2214 TCollection_AsciiString anAsciiList;
2215 Handle(TColStd_HSequenceOfTransient) aSeq;
2216 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2217 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2220 // Make a Python command
2222 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2223 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2225 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2226 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2227 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2233 //=============================================================================
2237 //=============================================================================
2238 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2239 (const Handle(GEOM_Object)& theShape,
2240 const Standard_Integer theShapeType,
2241 const Handle(GEOM_Object)& theCenter,
2242 const Standard_Real theRadius,
2243 const GEOMAlgo_State theState)
2247 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2249 TopoDS_Shape aShape = theShape->GetValue();
2250 TopoDS_Shape aCenter = theCenter->GetValue();
2252 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2254 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2255 if ( !checkTypeShapesOn( aShapeType ))
2258 // Center of the sphere
2259 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2260 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2262 gp_Ax3 anAx3 (aLoc, gp::DZ());
2263 Handle(Geom_SphericalSurface) aSphere =
2264 new Geom_SphericalSurface(anAx3, theRadius);
2267 TCollection_AsciiString anAsciiList;
2268 Handle(TColStd_HSequenceOfTransient) aSeq;
2269 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2270 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2273 // Make a Python command
2275 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2276 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2278 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2279 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2280 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2286 //=============================================================================
2288 * GetShapesOnPlaneIDs
2290 //=============================================================================
2291 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2292 (const Handle(GEOM_Object)& theShape,
2293 const Standard_Integer theShapeType,
2294 const Handle(GEOM_Object)& theAx1,
2295 const GEOMAlgo_State theState)
2299 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2301 TopoDS_Shape aShape = theShape->GetValue();
2302 TopoDS_Shape anAx1 = theAx1->GetValue();
2304 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2306 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2307 if ( !checkTypeShapesOn( aShapeType ))
2311 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2312 if ( aPlane.IsNull() )
2316 Handle(TColStd_HSequenceOfInteger) aSeq;
2317 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2319 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2320 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2322 // Make a Python command
2323 GEOM::TPythonDump(aFunction, /*append=*/true)
2324 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2325 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2331 //=============================================================================
2333 * GetShapesOnPlaneWithLocationIDs
2335 //=============================================================================
2336 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2337 (const Handle(GEOM_Object)& theShape,
2338 const Standard_Integer theShapeType,
2339 const Handle(GEOM_Object)& theAx1,
2340 const Handle(GEOM_Object)& thePnt,
2341 const GEOMAlgo_State theState)
2345 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2347 TopoDS_Shape aShape = theShape->GetValue();
2348 TopoDS_Shape anAx1 = theAx1->GetValue();
2349 TopoDS_Shape anPnt = thePnt->GetValue();
2351 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2353 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2354 if ( !checkTypeShapesOn( aShapeType ))
2358 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2359 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2360 TopoDS_Vertex V1, V2, V3;
2361 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2362 if (V1.IsNull() || V2.IsNull()) {
2363 SetErrorCode("Bad edge given for the plane normal vector");
2366 V3 = TopoDS::Vertex(anPnt);
2368 SetErrorCode("Bad vertex given for the plane location");
2371 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2372 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2373 if (aVec.Magnitude() < Precision::Confusion()) {
2374 SetErrorCode("Vector with null magnitude given");
2378 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2379 if ( aPlane.IsNull() )
2383 Handle(TColStd_HSequenceOfInteger) aSeq;
2384 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2386 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2387 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2389 // Make a Python command
2390 GEOM::TPythonDump(aFunction, /*append=*/true)
2391 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2392 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2398 //=============================================================================
2400 * GetShapesOnCylinderIDs
2402 //=============================================================================
2403 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2404 (const Handle(GEOM_Object)& theShape,
2405 const Standard_Integer theShapeType,
2406 const Handle(GEOM_Object)& theAxis,
2407 const Standard_Real theRadius,
2408 const GEOMAlgo_State theState)
2412 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2414 TopoDS_Shape aShape = theShape->GetValue();
2415 TopoDS_Shape anAxis = theAxis->GetValue();
2417 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2419 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2420 if ( !checkTypeShapesOn( aShapeType ))
2423 // Create a cylinder surface
2424 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2425 if ( aCylinder.IsNull() )
2429 Handle(TColStd_HSequenceOfInteger) aSeq;
2430 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2432 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2433 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2435 // Make a Python command
2436 GEOM::TPythonDump(aFunction, /*append=*/true)
2437 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2438 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2439 << theRadius << ", " << theState << ")";
2445 //=============================================================================
2447 * GetShapesOnSphereIDs
2449 //=============================================================================
2450 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2451 (const Handle(GEOM_Object)& theShape,
2452 const Standard_Integer theShapeType,
2453 const Handle(GEOM_Object)& theCenter,
2454 const Standard_Real theRadius,
2455 const GEOMAlgo_State theState)
2459 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2461 TopoDS_Shape aShape = theShape->GetValue();
2462 TopoDS_Shape aCenter = theCenter->GetValue();
2464 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2466 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2467 if ( !checkTypeShapesOn( aShapeType ))
2470 // Center of the sphere
2471 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2472 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2474 gp_Ax3 anAx3 (aLoc, gp::DZ());
2475 Handle(Geom_SphericalSurface) aSphere =
2476 new Geom_SphericalSurface(anAx3, theRadius);
2479 Handle(TColStd_HSequenceOfInteger) aSeq;
2480 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2482 // The GetShapesOnSphere() doesn't change object so no new function is required.
2483 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2485 // Make a Python command
2486 GEOM::TPythonDump(aFunction, /*append=*/true)
2487 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2488 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2489 << theRadius << ", " << theState << ")";
2495 //=======================================================================
2496 //function : getShapesOnQuadrangleIDs
2498 * \brief Find IDs of subshapes complying with given status about quadrangle
2499 * \param theShape - the shape to explore
2500 * \param theShapeType - type of subshape of theShape
2501 * \param theTopLeftPoint - top left quadrangle corner
2502 * \param theTopRigthPoint - top right quadrangle corner
2503 * \param theBottomLeftPoint - bottom left quadrangle corner
2504 * \param theBottomRigthPoint - bottom right quadrangle corner
2505 * \param theState - required state
2506 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2508 //=======================================================================
2509 Handle(TColStd_HSequenceOfInteger)
2510 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2511 const Standard_Integer theShapeType,
2512 const Handle(GEOM_Object)& theTopLeftPoint,
2513 const Handle(GEOM_Object)& theTopRigthPoint,
2514 const Handle(GEOM_Object)& theBottomLeftPoint,
2515 const Handle(GEOM_Object)& theBottomRigthPoint,
2516 const GEOMAlgo_State theState)
2520 if ( theShape.IsNull() ||
2521 theTopLeftPoint.IsNull() ||
2522 theTopRigthPoint.IsNull() ||
2523 theBottomLeftPoint.IsNull() ||
2524 theBottomRigthPoint.IsNull() )
2527 TopoDS_Shape aShape = theShape->GetValue();
2528 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2529 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2530 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2531 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2533 if (aShape.IsNull() ||
2538 aTL.ShapeType() != TopAbs_VERTEX ||
2539 aTR.ShapeType() != TopAbs_VERTEX ||
2540 aBL.ShapeType() != TopAbs_VERTEX ||
2541 aBR.ShapeType() != TopAbs_VERTEX )
2544 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2545 if ( !checkTypeShapesOn( aShapeType ))
2548 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2550 // Check presence of triangulation, build if need
2551 if (!CheckTriangulation(aShape)) {
2552 SetErrorCode("Cannot build triangulation on the shape");
2557 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2558 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2559 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2560 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2562 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2563 Standard_Real aTol = 0.0001; // default value
2565 aFinder.SetShape(aShape);
2566 aFinder.SetTolerance(aTol);
2567 //aFinder.SetSurface(theSurface);
2568 aFinder.SetShapeType(aShapeType);
2569 aFinder.SetState(theState);
2571 // Sets the minimal number of inner points for the faces that do not have own
2572 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2574 aFinder.SetNbPntsMin(3);
2575 // Sets the maximal number of inner points for edges or faces.
2576 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2577 // the performance. If this value =0, all inner points will be taken into account.
2579 aFinder.SetNbPntsMax(100);
2583 // Interprete results
2584 Standard_Integer iErr = aFinder.ErrorStatus();
2585 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2587 MESSAGE(" iErr : " << iErr);
2588 TCollection_AsciiString aMsg (" iErr : ");
2589 aMsg += TCollection_AsciiString(iErr);
2593 Standard_Integer iWrn = aFinder.WarningStatus();
2594 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2596 MESSAGE(" *** iWrn : " << iWrn);
2599 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2601 if (listSS.Extent() < 1) {
2602 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2603 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2607 // Fill sequence of object IDs
2608 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2610 TopTools_IndexedMapOfShape anIndices;
2611 TopExp::MapShapes(aShape, anIndices);
2613 TopTools_ListIteratorOfListOfShape itSub (listSS);
2614 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2615 int id = anIndices.FindIndex(itSub.Value());
2616 aSeqOfIDs->Append(id);
2621 //=======================================================================
2622 //function : GetShapesOnQuadrangle
2624 * \brief Find subshapes complying with given status about quadrangle
2625 * \param theShape - the shape to explore
2626 * \param theShapeType - type of subshape of theShape
2627 * \param theTopLeftPoint - top left quadrangle corner
2628 * \param theTopRigthPoint - top right quadrangle corner
2629 * \param theBottomLeftPoint - bottom left quadrangle corner
2630 * \param theBottomRigthPoint - bottom right quadrangle corner
2631 * \param theState - required state
2632 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2634 //=======================================================================
2635 Handle(TColStd_HSequenceOfTransient)
2636 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2637 const Standard_Integer theShapeType,
2638 const Handle(GEOM_Object)& theTopLeftPoint,
2639 const Handle(GEOM_Object)& theTopRigthPoint,
2640 const Handle(GEOM_Object)& theBottomLeftPoint,
2641 const Handle(GEOM_Object)& theBottomRigthPoint,
2642 const GEOMAlgo_State theState)
2645 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2646 getShapesOnQuadrangleIDs( theShape,
2651 theBottomRigthPoint,
2653 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2656 // Find objects by indices
2657 TCollection_AsciiString anAsciiList;
2658 Handle(TColStd_HSequenceOfTransient) aSeq;
2659 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2660 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2663 // Make a Python command
2665 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2666 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2668 GEOM::TPythonDump(aFunction)
2669 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2671 << TopAbs_ShapeEnum(theShapeType) << ", "
2672 << theTopLeftPoint << ", "
2673 << theTopRigthPoint << ", "
2674 << theBottomLeftPoint << ", "
2675 << theBottomRigthPoint << ", "
2682 //=======================================================================
2683 //function : GetShapesOnQuadrangleIDs
2685 * \brief Find IDs of subshapes complying with given status about quadrangle
2686 * \param theShape - the shape to explore
2687 * \param theShapeType - type of subshape of theShape
2688 * \param theTopLeftPoint - top left quadrangle corner
2689 * \param theTopRigthPoint - top right quadrangle corner
2690 * \param theBottomLeftPoint - bottom left quadrangle corner
2691 * \param theBottomRigthPoint - bottom right quadrangle corner
2692 * \param theState - required state
2693 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2695 //=======================================================================
2696 Handle(TColStd_HSequenceOfInteger)
2697 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2698 const Standard_Integer theShapeType,
2699 const Handle(GEOM_Object)& theTopLeftPoint,
2700 const Handle(GEOM_Object)& theTopRigthPoint,
2701 const Handle(GEOM_Object)& theBottomLeftPoint,
2702 const Handle(GEOM_Object)& theBottomRigthPoint,
2703 const GEOMAlgo_State theState)
2706 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2707 getShapesOnQuadrangleIDs( theShape,
2712 theBottomRigthPoint,
2714 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2717 // Make a Python command
2719 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2720 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2721 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2722 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2723 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2724 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2726 GEOM::TPythonDump(aFunction, /*append=*/true)
2727 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2729 << TopAbs_ShapeEnum(theShapeType) << ", "
2730 << theTopLeftPoint << ", "
2731 << theTopRigthPoint << ", "
2732 << theBottomLeftPoint << ", "
2733 << theBottomRigthPoint << ", "
2740 //=============================================================================
2744 //=============================================================================
2745 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2746 const TopTools_IndexedMapOfShape& theWhereIndices,
2747 const TopoDS_Shape& theWhat,
2748 TColStd_ListOfInteger& theModifiedList)
2750 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2752 if (theWhereIndices.Contains(theWhat)) {
2753 // entity was not changed by the operation
2754 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2755 theModifiedList.Append(aWhatIndex);
2759 // try to find in history
2760 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2762 // search in history for all argument shapes
2763 Standard_Boolean isFound = Standard_False;
2764 Standard_Boolean isGood = Standard_False;
2766 TDF_LabelSequence aLabelSeq;
2767 theWhereFunction->GetDependency(aLabelSeq);
2768 Standard_Integer nbArg = aLabelSeq.Length();
2770 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2772 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2774 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2775 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2777 TopTools_IndexedMapOfShape anArgumentIndices;
2778 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2780 if (anArgumentIndices.Contains(theWhat)) {
2781 isFound = Standard_True;
2782 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2784 // Find corresponding label in history
2785 TDF_Label anArgumentHistoryLabel =
2786 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2787 if (anArgumentHistoryLabel.IsNull()) {
2788 // Lost History of operation argument. Possibly, all its entities was removed.
2789 isGood = Standard_True;
2792 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2794 if (aWhatHistoryLabel.IsNull()) {
2795 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2796 isGood = Standard_False;
2798 Handle(TDataStd_IntegerArray) anIntegerArray;
2799 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2800 //Error: Empty modifications history for the sought shape.
2801 isGood = Standard_False;
2804 isGood = Standard_True;
2805 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2806 for (imod = 1; imod <= aModifLen; imod++) {
2807 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2818 // try compound/compsolid/shell/wire element by element
2819 bool isFoundAny = false;
2820 TopTools_MapOfShape mapShape;
2822 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2823 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2824 // recursive processing of compound/compsolid
2825 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2826 for (; anIt.More(); anIt.Next()) {
2827 if (mapShape.Add(anIt.Value())) {
2828 TopoDS_Shape curWhat = anIt.Value();
2829 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2830 if (isFoundAny) isFound = Standard_True;
2834 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2835 // try to replace a shell by its faces images
2836 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2837 for (; anExp.More(); anExp.Next()) {
2838 if (mapShape.Add(anExp.Current())) {
2839 TopoDS_Shape curWhat = anExp.Current();
2840 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2841 if (isFoundAny) isFound = Standard_True;
2845 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2846 // try to replace a wire by its edges images
2847 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2848 for (; anExp.More(); anExp.Next()) {
2849 if (mapShape.Add(anExp.Current())) {
2850 TopoDS_Shape curWhat = anExp.Current();
2851 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2852 if (isFoundAny) isFound = Standard_True;
2864 //=============================================================================
2866 * GetShapeProperties
2868 //=============================================================================
2869 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
2872 GProp_GProps theProps;
2874 //TopoDS_Shape aPntShape;
2875 Standard_Real aShapeSize;
2877 if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
2878 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
2879 else BRepGProp::VolumeProperties(aShape, theProps);
2881 aCenterMass = theProps.CentreOfMass();
2882 aShapeSize = theProps.Mass();
2884 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
2885 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
2886 aVertex = aCenterMass;
2887 tab[0] = aVertex.X();
2888 tab[1] = aVertex.Y();
2889 tab[2] = aVertex.Z();
2890 tab[3] = aShapeSize;
2896 //================================================================================
2898 * \brief Return normal to face at extrema point
2900 //================================================================================
2902 gp_Vec GetNormal(const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
2904 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
2906 // get UV at extrema point
2907 Standard_Real u,v, f,l;
2908 switch ( extrema.SupportTypeShape2(1) ) {
2909 case BRepExtrema_IsInFace: {
2910 extrema.ParOnFaceS2(1, u, v );
2913 case BRepExtrema_IsOnEdge: {
2914 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
2915 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
2916 extrema.ParOnEdgeS2( 1, u );
2917 gp_Pnt2d uv = pcurve->Value( u );
2922 case BRepExtrema_IsVertex: return defaultNorm;
2925 BRepAdaptor_Surface surface( face, false );
2926 gp_Vec du, dv; gp_Pnt p;
2927 surface.D1( u, v, p, du, dv );
2931 } catch (Standard_Failure ) {
2937 //=============================================================================
2942 //=============================================================================
2943 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
2944 Handle(GEOM_Object) theShapeWhat)
2948 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2950 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2951 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2952 TopoDS_Shape aPntShape;
2953 TopoDS_Vertex aVertex;
2955 if (aWhere.IsNull() || aWhat.IsNull()) {
2956 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
2960 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2961 if (aWhereFunction.IsNull()) {
2962 SetErrorCode("Error: aWhereFunction is Null.");
2966 TopTools_IndexedMapOfShape aWhereIndices;
2967 TopExp::MapShapes(aWhere, aWhereIndices);
2969 TColStd_ListOfInteger aModifiedList;
2970 Standard_Integer aWhereIndex;
2971 Handle(TColStd_HArray1OfInteger) aModifiedArray;
2972 Handle(GEOM_Object) aResult;
2974 bool isFound = false;
2975 Standard_Integer iType = TopAbs_SOLID;
2976 Standard_Integer compType = TopAbs_SOLID;
2977 Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
2978 Standard_Real tab_aWhat[4], tab_aWhere[4];
2979 Standard_Real dl_l = 1e-3;
2980 Standard_Real min_l, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
2981 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2982 Bnd_Box BoundingBox;
2983 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
2984 GProp_GProps aProps;
2986 // Find the iType of the aWhat shape
2987 if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
2988 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
2989 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
2990 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
2991 // Only the iType of the first shape in the compound is taken into account
2992 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
2994 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
2997 compType = It.Value().ShapeType();
2998 if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
2999 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
3000 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
3003 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3007 TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
3008 TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
3009 TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
3011 // Find the shortest edge in theShapeWhere shape
3012 BRepBndLib::Add(aWhere, BoundingBox);
3013 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3014 min_l = fabs(aXmax - aXmin);
3015 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3016 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3018 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3019 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3020 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3021 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3022 tab_Pnt[nbVertex] = aPnt;
3024 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3025 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3026 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3030 // Compute tolerances
3031 Tol_1D = dl_l * min_l;
3032 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3033 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3035 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3036 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3037 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3040 if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3041 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3043 // Compute the ShapeWhat Mass
3044 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
3045 if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
3046 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
3047 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
3048 aWhat_Mass += aProps.Mass();
3051 // Searching for the sub-shapes inside the ShapeWhere shape
3052 TopTools_MapOfShape map_aWhere;
3053 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
3054 if (!map_aWhere.Add(Exp_aWhere.Current()))
3055 continue; // skip repeated shape to avoid mass addition
3056 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
3057 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
3058 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
3059 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
3062 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
3063 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
3064 aVertex = TopoDS::Vertex( aPntShape );
3065 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
3066 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
3067 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
3068 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
3070 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
3071 // aVertex must be projected to the same point on Where and on What
3072 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
3073 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
3074 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
3075 if ( isFound && iType == TopAbs_FACE )
3077 // check normals at pOnWhat and pOnWhere
3078 const double angleTol = PI/180.;
3079 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
3080 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
3081 if ( normToWhat * normToWhere < 0 )
3082 normToWhat.Reverse();
3083 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
3089 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
3090 aModifiedList.Append(aWhereIndex);
3091 aWhere_Mass += tab_aWhere[3];
3096 if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) break;
3099 if (aModifiedList.Extent() == 0) { // Not found any Results
3100 SetErrorCode(NOT_FOUND_ANY);
3104 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3105 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3106 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
3107 aModifiedArray->SetValue(imod, anIterModif.Value());
3110 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3111 if (aResult.IsNull()) {
3112 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3116 if (aModifiedArray->Length() > 1) {
3118 aResult->SetType(GEOM_GROUP);
3120 //Set a sub shape type
3121 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3122 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3124 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3125 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3128 //Make a Python command
3129 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3131 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3132 << theShapeWhere << ", " << theShapeWhat << ")";
3138 //=======================================================================
3139 //function : GetInPlaceByHistory
3141 //=======================================================================
3142 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
3143 (Handle(GEOM_Object) theShapeWhere,
3144 Handle(GEOM_Object) theShapeWhat)
3148 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3150 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3151 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3153 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3155 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3156 if (aWhereFunction.IsNull()) return NULL;
3158 //Fill array of indices
3159 TopTools_IndexedMapOfShape aWhereIndices;
3160 TopExp::MapShapes(aWhere, aWhereIndices);
3163 TColStd_ListOfInteger aModifiedList;
3164 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3166 if (!isFound || aModifiedList.Extent() < 1) {
3167 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3171 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3172 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3173 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3174 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3175 aModifiedArray->SetValue(imod, anIterModif.Value());
3179 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3180 if (aResult.IsNull()) {
3181 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3185 if (aModifiedArray->Length() > 1) {
3187 aResult->SetType(GEOM_GROUP);
3189 //Set a sub shape type
3190 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3191 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3193 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3194 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3197 //Make a Python command
3198 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3200 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
3201 << theShapeWhere << ", " << theShapeWhat << ")";
3207 //=======================================================================
3208 //function : SortShapes
3210 //=======================================================================
3211 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
3213 Standard_Integer MaxShapes = SL.Extent();
3214 TopTools_Array1OfShape aShapes (1,MaxShapes);
3215 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3216 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3217 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3219 // Computing of CentreOfMass
3220 Standard_Integer Index;
3223 TopTools_ListIteratorOfListOfShape it(SL);
3224 for (Index=1; it.More(); Index++)
3226 TopoDS_Shape S = it.Value();
3227 SL.Remove( it ); // == it.Next()
3229 OrderInd.SetValue (Index, Index);
3230 if (S.ShapeType() == TopAbs_VERTEX)
3232 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3233 Length.SetValue( Index, (Standard_Real) S.Orientation());
3237 BRepGProp::LinearProperties (S, GPr);
3238 GPoint = GPr.CentreOfMass();
3239 Length.SetValue( Index, GPr.Mass() );
3241 MidXYZ.SetValue(Index,
3242 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3243 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3247 Standard_Integer aTemp;
3248 Standard_Boolean exchange, Sort = Standard_True;
3249 Standard_Real tol = Precision::Confusion();
3252 Sort = Standard_False;
3253 for (Index=1; Index < MaxShapes; Index++)
3255 exchange = Standard_False;
3256 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3257 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3258 if ( dMidXYZ >= tol ) {
3259 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3260 // << " d: " << dMidXYZ << endl;
3261 exchange = Standard_True;
3263 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3264 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3265 // << " d: " << dLength << endl;
3266 exchange = Standard_True;
3268 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3269 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3271 // equal values possible on shapes such as two halves of a sphere and
3272 // a membrane inside the sphere
3274 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3275 if ( box1.IsVoid() ) continue;
3276 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3277 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3278 if ( dSquareExtent >= tol ) {
3279 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3280 exchange = Standard_True;
3282 else if ( Abs(dSquareExtent) < tol ) {
3283 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3284 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3285 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3286 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3287 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3288 //exchange = val1 > val2;
3289 if ((val1 - val2) >= tol) {
3290 exchange = Standard_True;
3292 //cout << "box: " << val1<<" > "<<val2 << endl;
3298 // cout << "exchange " << Index << " & " << Index+1 << endl;
3299 aTemp = OrderInd(Index);
3300 OrderInd(Index) = OrderInd(Index+1);
3301 OrderInd(Index+1) = aTemp;
3302 Sort = Standard_True;
3307 for (Index=1; Index <= MaxShapes; Index++)
3308 SL.Append( aShapes( OrderInd(Index) ));
3311 //=======================================================================
3312 //function : CompsolidToCompound
3314 //=======================================================================
3315 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3317 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3318 return theCompsolid;
3321 TopoDS_Compound aCompound;
3323 B.MakeCompound(aCompound);
3325 TopTools_MapOfShape mapShape;
3326 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3328 for (; It.More(); It.Next()) {
3329 TopoDS_Shape aShape_i = It.Value();
3330 if (mapShape.Add(aShape_i)) {
3331 B.Add(aCompound, aShape_i);
3338 //=======================================================================
3339 //function : CheckTriangulation
3341 //=======================================================================
3342 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3344 bool isTriangulation = true;
3346 TopExp_Explorer exp (aShape, TopAbs_FACE);
3349 TopLoc_Location aTopLoc;
3350 Handle(Poly_Triangulation) aTRF;
3351 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3352 if (aTRF.IsNull()) {
3353 isTriangulation = false;
3356 else // no faces, try edges
3358 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3362 TopLoc_Location aLoc;
3363 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3365 isTriangulation = false;
3369 if (!isTriangulation) {
3370 // calculate deflection
3371 Standard_Real aDeviationCoefficient = 0.001;
3374 BRepBndLib::Add(aShape, B);
3375 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3376 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3378 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3379 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3380 Standard_Real aHLRAngle = 0.349066;
3382 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3388 #define MAX_TOLERANCE 1.e-7
3390 //=======================================================================
3391 //function : isSameEdge
3392 //purpose : Returns True if two edges coincide
3393 //=======================================================================
3394 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3396 TopoDS_Vertex V11, V12, V21, V22;
3397 TopExp::Vertices(theEdge1, V11, V12);
3398 TopExp::Vertices(theEdge2, V21, V22);
3399 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3400 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3401 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3402 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3403 bool coincide = false;
3405 //Check that ends of edges coincide
3406 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3407 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3409 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3410 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3413 if(!coincide) return false;
3415 if (BRep_Tool::Degenerated(theEdge1))
3416 if (BRep_Tool::Degenerated(theEdge2)) return true;
3419 if (BRep_Tool::Degenerated(theEdge2)) return false;
3421 double U11, U12, U21, U22;
3422 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3423 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3424 if(C1->DynamicType() == C2->DynamicType()) return true;
3426 //Check that both edges has the same geometry
3427 double range = U12-U11;
3428 double U = U11+ range/3.0;
3429 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3430 U = U11+range*2.0/3.0;
3431 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3433 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3436 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3438 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3441 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3446 #include <TopoDS_TShape.hxx>
3447 //=======================================================================
3448 //function : isSameFace
3449 //purpose : Returns True if two faces coincide
3450 //=======================================================================
3451 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3453 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3454 TopTools_ListOfShape LS1, LS2;
3455 for(; E.More(); E.Next()) LS1.Append(E.Current());
3457 E.Init(theFace2, TopAbs_EDGE);
3458 for(; E.More(); E.Next()) LS2.Append(E.Current());
3460 //Compare the number of edges in the faces
3461 if(LS1.Extent() != LS2.Extent()) return false;
3463 double aMin = RealFirst(), aMax = RealLast();
3464 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3465 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3467 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3468 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3469 if(P.X() < xminB1) xminB1 = P.X();
3470 if(P.Y() < yminB1) yminB1 = P.Y();
3471 if(P.Z() < zminB1) zminB1 = P.Z();
3472 if(P.X() > xmaxB1) xmaxB1 = P.X();
3473 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3474 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3477 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3478 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3479 if(P.X() < xminB2) xminB2 = P.X();
3480 if(P.Y() < yminB2) yminB2 = P.Y();
3481 if(P.Z() < zminB2) zminB2 = P.Z();
3482 if(P.X() > xmaxB2) xmaxB2 = P.X();
3483 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3484 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3487 //Compare the bounding boxes of both faces
3488 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3491 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3494 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3495 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3497 //Check if there a coincidence of two surfaces at least in two points
3498 double U11, U12, V11, V12, U21, U22, V21, V22;
3499 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3500 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3502 double rangeU = U12-U11;
3503 double rangeV = V12-V11;
3504 double U = U11 + rangeU/3.0;
3505 double V = V11 + rangeV/3.0;
3506 gp_Pnt P1 = S1->Value(U, V);
3507 U = U11+rangeU*2.0/3.0;
3508 V = V11+rangeV*2.0/3.0;
3509 gp_Pnt P2 = S1->Value(U, V);
3511 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3514 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3516 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3519 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3521 //Check that each edge of the Face1 has a counterpart in the Face2
3522 TopTools_MapOfOrientedShape aMap;
3523 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3524 for(; LSI1.More(); LSI1.Next()) {
3525 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3526 bool isFound = false;
3527 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3528 for(; LSI2.More(); LSI2.Next()) {
3529 TopoDS_Shape aValue = LSI2.Value();
3530 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3531 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3537 if(!isFound) return false;
3543 //=======================================================================
3544 //function : isSameSolid
3545 //purpose : Returns True if two solids coincide
3546 //=======================================================================
3547 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3549 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3550 TopTools_ListOfShape LS1, LS2;
3551 for(; E.More(); E.Next()) LS1.Append(E.Current());
3552 E.Init(theSolid2, TopAbs_FACE);
3553 for(; E.More(); E.Next()) LS2.Append(E.Current());
3555 if(LS1.Extent() != LS2.Extent()) return false;
3557 double aMin = RealFirst(), aMax = RealLast();
3558 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3559 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3561 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3562 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3563 if(P.X() < xminB1) xminB1 = P.X();
3564 if(P.Y() < yminB1) yminB1 = P.Y();
3565 if(P.Z() < zminB1) zminB1 = P.Z();
3566 if(P.X() > xmaxB1) xmaxB1 = P.X();
3567 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3568 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3571 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
3572 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3573 if(P.X() < xminB2) xminB2 = P.X();
3574 if(P.Y() < yminB2) yminB2 = P.Y();
3575 if(P.Z() < zminB2) zminB2 = P.Z();
3576 if(P.X() > xmaxB2) xmaxB2 = P.X();
3577 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3578 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3581 //Compare the bounding boxes of both solids
3582 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3585 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3588 //Check that each face of the Solid1 has a counterpart in the Solid2
3589 TopTools_MapOfOrientedShape aMap;
3590 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3591 for(; LSI1.More(); LSI1.Next()) {
3592 TopoDS_Face F = TopoDS::Face(LSI1.Value());
3593 bool isFound = false;
3594 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3595 for(; LSI2.More(); LSI2.Next()) {
3596 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
3597 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
3598 aMap.Add(LSI2.Value());
3603 if(!isFound) return false;
3609 //=======================================================================
3610 //function : GetSame
3612 //=======================================================================
3613 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
3614 const Handle(GEOM_Object)& theShapeWhat)
3617 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3619 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3620 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3622 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3625 bool isFound = false;
3626 TopoDS_Shape aSubShape;
3627 TopTools_MapOfShape aMap;
3629 switch(aWhat.ShapeType()) {
3630 case TopAbs_VERTEX: {
3631 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
3632 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
3633 for(; E.More(); E.Next()) {
3634 if(!aMap.Add(E.Current())) continue;
3635 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3636 if(P.Distance(P2) <= MAX_TOLERANCE) {
3638 aSubShape = E.Current();
3645 TopoDS_Face aFace = TopoDS::Face(aWhat);
3646 TopExp_Explorer E(aWhere, TopAbs_FACE);
3647 for(; E.More(); E.Next()) {
3648 if(!aMap.Add(E.Current())) continue;
3649 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
3650 aSubShape = E.Current();
3658 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3659 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3660 for(; E.More(); E.Next()) {
3661 if(!aMap.Add(E.Current())) continue;
3662 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3663 aSubShape = E.Current();
3670 case TopAbs_SOLID: {
3671 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3672 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3673 for(; E.More(); E.Next()) {
3674 if(!aMap.Add(E.Current())) continue;
3675 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3676 aSubShape = E.Current();
3688 TopTools_IndexedMapOfShape anIndices;
3689 TopExp::MapShapes(aWhere, anIndices);
3690 if (anIndices.Contains(aSubShape))
3691 anIndex = anIndices.FindIndex(aSubShape);
3694 if(anIndex < 0) return NULL;
3696 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3698 anArray->SetValue(1, anIndex);
3700 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3701 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3703 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3704 << theShapeWhere << ", " << theShapeWhat << ")";