X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_IShapesOperations.cxx;h=68231130216ea6a1bcf1ebba3bb98498ad6e3b24;hb=48f5c2df5815348d168fd8e80fcc9e52dd69f137;hp=9b4f0e9b84e247cb3be6770b1724ebdbc005f8ab;hpb=723f0c59fbe9ee4bc11f11513a971fd4e691b55d;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index 9b4f0e9b8..682311302 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -1,23 +1,23 @@ -// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // File : GEOMImpl_IShapesOperations.cxx // Created : @@ -40,21 +40,27 @@ #include "GEOMImpl_IGlue.hxx" #include "GEOMImpl_Block6Explorer.hxx" +#include "GEOMImpl_IHealingOperations.hxx" + +#include #include "GEOM_Function.hxx" #include "GEOM_ISubShape.hxx" #include "GEOM_PythonDump.hxx" +#include "GEOMAlgo_ClsfBox.hxx" +#include "GEOMAlgo_ClsfSolid.hxx" +#include "GEOMAlgo_CoupleOfShapes.hxx" #include "GEOMAlgo_FinderShapeOn1.hxx" #include "GEOMAlgo_FinderShapeOnQuad.hxx" #include "GEOMAlgo_FinderShapeOn2.hxx" -#include "GEOMAlgo_ClsfBox.hxx" -#include "GEOMAlgo_ClsfSolid.hxx" -#include "GEOMAlgo_Gluer1.hxx" +#include "GEOMAlgo_GetInPlace.hxx" +#include "GEOMAlgo_GlueDetector.hxx" #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx" -#include "GEOMAlgo_CoupleOfShapes.hxx" #include "GEOMAlgo_ListOfCoupleOfShapes.hxx" +#include + #include "utilities.h" #include "OpUtil.hxx" #include "Utils_ExceptHandlers.hxx" @@ -77,11 +83,12 @@ #include #include #include -#include #include #include #include +#include +#include #include #include #include @@ -90,13 +97,12 @@ #include #include #include -#include -#include -#include -#include #include -#include +#include #include +#include +#include +#include #include #include @@ -118,6 +124,8 @@ #include #include +#include +#include #include #include @@ -133,6 +141,8 @@ #include #include +#define STD_SORT_ALGO 1 + //============================================================================= /*! * constructor: @@ -187,7 +197,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge //Compute the Edge value try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif if (!GetSolver()->ComputeFunction(aFunction)) { @@ -248,7 +258,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength //Compute the Edge value try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif if (!GetSolver()->ComputeFunction(aFunction)) { @@ -306,7 +316,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire //Compute the Edge value try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif if (!GetSolver()->ComputeFunction(aFunction)) { @@ -382,7 +392,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire //Compute the shape try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif if (!GetSolver()->ComputeFunction(aFunction)) { @@ -447,8 +457,9 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) th aCI.SetIsPlanar(isPlanarWanted); //Compute the Face value + Standard_Boolean isWarning = Standard_False; try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif if (!GetSolver()->ComputeFunction(aFunction)) { @@ -459,14 +470,20 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) th catch (Standard_Failure) { Handle(Standard_Failure) aFail = Standard_Failure::Caught(); SetErrorCode(aFail->GetMessageString()); - return NULL; + // to provide warning + if (!aFunction->GetValue().IsNull()) { + isWarning = Standard_True; + } else { + return NULL; + } } //Make a Python command GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace(" << theWire << ", " << (int)isPlanarWanted << ")"; - SetErrorCode(OK); + // to provide warning + if (!isWarning) SetErrorCode(OK); return aFace; } @@ -511,8 +528,9 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires aCI.SetIsPlanar(isPlanarWanted); //Compute the shape + Standard_Boolean isWarning = Standard_False; try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif if (!GetSolver()->ComputeFunction(aFunction)) { @@ -523,7 +541,12 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires catch (Standard_Failure) { Handle(Standard_Failure) aFail = Standard_Failure::Caught(); SetErrorCode(aFail->GetMessageString()); - return NULL; + // to provide warning + if (!aFunction->GetValue().IsNull()) { + isWarning = Standard_True; + } else { + return NULL; + } } //Make a Python command @@ -540,7 +563,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires } pd << "], " << (int)isPlanarWanted << ")"; - SetErrorCode(OK); + // to provide warning + if (!isWarning) SetErrorCode(OK); return aShape; } @@ -619,7 +643,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape //Compute the shape try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif if (!GetSolver()->ComputeFunction(aFunction)) { @@ -688,7 +712,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces //Compute the sub-shape value Standard_Boolean isWarning = Standard_False; try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif if (!GetSolver()->ComputeFunction(aFunction)) { @@ -721,6 +745,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces * GetGlueFaces */ //============================================================================= +/* Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces (Handle(GEOM_Object) theShape, const Standard_Real theTolerance) @@ -781,7 +806,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces if( anAsciiList.Length() > 0 ) { anAsciiList.Trunc(anAsciiList.Length() - 1); Handle(GEOM_Function) aFunction = theShape->GetLastFunction(); - GEOM::TPythonDump pd (aFunction, /*append=*/true); + GEOM::TPythonDump pd (aFunction, true); pd << "[" << anAsciiList.ToCString(); pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")"; } @@ -790,6 +815,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces return aSeq; } +*/ //============================================================================= /*! @@ -800,7 +826,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList (Handle(GEOM_Object) theShape, const Standard_Real theTolerance, std::list theFaces, - const Standard_Boolean doKeepNonSolids) + const Standard_Boolean doKeepNonSolids, + const Standard_Boolean doGlueAllEdges) { SetErrorCode(KO); @@ -825,6 +852,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList aCI.SetBase(aRefShape); aCI.SetTolerance(theTolerance); aCI.SetKeepNonSolids(doKeepNonSolids); + aCI.SetGlueAllEdges(doGlueAllEdges); Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient; std::list::iterator it = theFaces.begin(); @@ -841,7 +869,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList //Compute the sub-shape value Standard_Boolean isWarning = Standard_False; try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif if (!GetSolver()->ComputeFunction(aFunction)) { @@ -873,6 +901,244 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList pd << ", " << (*it++); } } + pd << "], " << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")"; + + // to provide warning + if (!isWarning) SetErrorCode(OK); + return aGlued; +} + +//============================================================================= +/*! + * MakeGlueEdges + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdges + (Handle(GEOM_Object) theShape, + const Standard_Real theTolerance) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return NULL; + + //Add a new Glued object + Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED); + + //Add a new Glue function + Handle(GEOM_Function) aFunction; + aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL; + + GEOMImpl_IGlue aCI (aFunction); + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return NULL; + + aCI.SetBase(aRefShape); + aCI.SetTolerance(theTolerance); + aCI.SetKeepNonSolids(true); + + //Compute the sub-shape value + Standard_Boolean isWarning = Standard_False; + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Shape driver failed to glue edges"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + // to provide warning + if (!aFunction->GetValue().IsNull()) { + isWarning = Standard_True; + } else { + return NULL; + } + } + + //Make a Python command + GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges(" + << theShape << ", " << theTolerance << ")"; + + // to provide warning + if (!isWarning) SetErrorCode(OK); + return aGlued; +} + +//============================================================================= +/*! + * GetGlueShapes + */ +//============================================================================= +Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueShapes + (Handle(GEOM_Object) theShape, + const Standard_Real theTolerance, + const TopAbs_ShapeEnum theType) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return NULL; + TopoDS_Shape aShape = theShape->GetValue(); + if (aShape.IsNull()) return NULL; + + Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient; + + GEOMAlgo_GlueDetector aGluer; + aGluer.SetArgument(aShape); + aGluer.SetTolerance(theTolerance); + aGluer.Perform(); + Standard_Integer iErr = aGluer.ErrorStatus(); + if (iErr) return NULL; + + TCollection_AsciiString anAsciiList, anEntry; + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + Handle(TColStd_HArray1OfInteger) anArray; + Handle(GEOM_Object) anObj; + + TopTools_ListOfShape listOnePerSet; + + const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images(); + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages); + for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) { + // some key shape + //const TopoDS_Shape& aSkey = aItDMSLS.Key(); + + // list of shapes of the argument that can be glued + const TopTools_ListOfShape& aLSD = aItDMSLS.Value(); + + //listShape.Append(aLSD.First()); + TopoDS_Shape aValue = aLSD.First(); + + if (aValue.ShapeType() == theType) { + listOnePerSet.Append(aValue); + } + } + + // for stable order of returned entities + GEOMImpl_IShapesOperations::SortShapes(listOnePerSet, Standard_False); + + TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet); + for (; aListIt.More(); aListIt.Next()) { + TopoDS_Shape aValue = aListIt.Value(); + anArray = new TColStd_HArray1OfInteger(1,1); + anArray->SetValue(1, anIndices.FindIndex(aValue)); + anObj = GetEngine()->AddSubShape(theShape, anArray); + if (!anObj.IsNull()) { + aSeq->Append(anObj); + + // for python command + TDF_Tool::Entry(anObj->GetEntry(), anEntry); + anAsciiList += anEntry; + anAsciiList += ","; + } + } + + // Make a Python command + if (anAsciiList.Length() > 0) { + anAsciiList.Trunc(anAsciiList.Length() - 1); + Handle(GEOM_Function) aFunction = theShape->GetLastFunction(); + GEOM::TPythonDump pd (aFunction, /*append=*/true); + pd << "[" << anAsciiList.ToCString(); + if (theType == TopAbs_FACE) + pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")"; + else if (theType == TopAbs_EDGE) + pd << "] = geompy.GetGlueEdges(" << theShape << ", " << theTolerance << ")"; + } + + SetErrorCode(OK); + + return aSeq; +} + +//============================================================================= +/*! + * MakeGlueEdgesByList + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdgesByList + (Handle(GEOM_Object) theShape, + const Standard_Real theTolerance, + std::list theEdges) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return NULL; + + //Add a new Glued object + Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED); + + //Add a new Glue function + Handle(GEOM_Function) aFunction; + aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL; + + GEOMImpl_IGlue aCI (aFunction); + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return NULL; + + aCI.SetBase(aRefShape); + aCI.SetTolerance(theTolerance); + aCI.SetKeepNonSolids(true); + + Handle(TColStd_HSequenceOfTransient) anEdges = new TColStd_HSequenceOfTransient; + std::list::iterator it = theEdges.begin(); + for (; it != theEdges.end(); it++) { + Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction(); + if (aRefSh.IsNull()) { + SetErrorCode("NULL argument shape for the shape construction"); + return NULL; + } + anEdges->Append(aRefSh); + } + aCI.SetFaces(anEdges); + + //Compute the sub-shape value + Standard_Boolean isWarning = Standard_False; + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Shape driver failed to glue edges"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + // to provide warning + if (!aFunction->GetValue().IsNull()) { + isWarning = Standard_True; + } else { + return NULL; + } + } + + //Make a Python command + + GEOM::TPythonDump pd (aFunction); + pd << aGlued << " = geompy.MakeGlueEdgesByList(" + << theShape << ", " << theTolerance << ", ["; + // Edges + it = theEdges.begin(); + if (it != theEdges.end()) { + pd << (*it++); + while (it != theEdges.end()) { + pd << ", " << (*it++); + } + } pd << "])"; // to provide warning @@ -937,7 +1203,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetExistingSubO GEOM::TPythonDump pd (aMainShape, /*append=*/true); pd << "[" << anAsciiList.ToCString(); pd << "] = geompy.GetExistingSubObjects("; - pd << theShape << ", " << (int)theGroupsOnly << ")"; + pd << theShape << ", " << (bool)theGroupsOnly << ")"; SetErrorCode(OK); @@ -1031,6 +1297,9 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape // on the main shape for each being calculated sub-shape separately. aFunction->SetValue(aValue); + + // Put this subshape in the list of sub-shapes of theMainShape + aMainShape->AddSubShapeReference(aFunction); } if (!anObj.IsNull()) { @@ -1191,40 +1460,123 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape //============================================================================= /*! - * GetSubShapeIndex + * MakeSubShapes */ //============================================================================= -Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape, - Handle(GEOM_Object) theSubShape) +Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes + (Handle(GEOM_Object) theMainShape, + Handle(TColStd_HArray1OfInteger) theIndices) { SetErrorCode(KO); - TopoDS_Shape aMainShape = theMainShape->GetValue(); - TopoDS_Shape aSubShape = theSubShape->GetValue(); - - if (aMainShape.IsNull() || aSubShape.IsNull()) return -1; + Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient; - TopTools_IndexedMapOfShape anIndices; - TopExp::MapShapes(aMainShape, anIndices); - if (anIndices.Contains(aSubShape)) { - SetErrorCode(OK); - return anIndices.FindIndex(aSubShape); + if (!theIndices->Length()) { + SetErrorCode(NOT_FOUND_ANY); + return aSeq; } - return -1; -} + if (theMainShape.IsNull()) return NULL; + TopoDS_Shape aShape = theMainShape->GetValue(); + if (aShape.IsNull()) return NULL; -//============================================================================= -/*! - * GetTopologyIndex - */ -//============================================================================= -Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape, - Handle(GEOM_Object) theSubShape) -{ - SetErrorCode(OK); + Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction(); - TopoDS_Shape aMainShape = theMainShape->GetValue(); + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + + Handle(TColStd_HArray1OfInteger) anArray; + Handle(GEOM_Object) anObj; + + TCollection_AsciiString anAsciiList, anEntry; + Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper(); + for (i = low; i <= up; i++) { + int id = theIndices->Value(i); + if (1 <= id && id <= anIndices.Extent()) { + TopoDS_Shape aValue = anIndices.FindKey(id); + anArray = new TColStd_HArray1OfInteger(1,1); + anArray->SetValue(1, id); + + anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE); + if (!anObj.IsNull()) { + Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1); + if (aFunction.IsNull()) return aSeq; + + GEOM_ISubShape aSSI (aFunction); + aSSI.SetMainShape(aMainShape); + aSSI.SetIndices(anArray); + + // Set function value directly, as we know it. + // Usage of Solver here would lead to significant loss of time, + // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape + // on the main shape for each being calculated sub-shape separately. + aFunction->SetValue(aValue); + + // Put this sub-shape in the list of sub-shapes of theMainShape + aMainShape->AddSubShapeReference(aFunction); + + aSeq->Append(anObj); + + // for python command + TDF_Tool::Entry(anObj->GetEntry(), anEntry); + anAsciiList += anEntry; + anAsciiList += ","; + } + } + } + + //Make a Python command + anAsciiList.Trunc(anAsciiList.Length() - 1); + + GEOM::TPythonDump pd (aMainShape, /*append=*/true); + pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes(" + << theMainShape << ", [" ; + for (i = low; i <= up - 1; i++) { + pd << theIndices->Value(i) << ", "; + } + pd << theIndices->Value(up) << "])"; + + SetErrorCode(OK); + + return aSeq; +} + +//============================================================================= +/*! + * GetSubShapeIndex + */ +//============================================================================= +Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape, + Handle(GEOM_Object) theSubShape) +{ + SetErrorCode(KO); + + TopoDS_Shape aMainShape = theMainShape->GetValue(); + TopoDS_Shape aSubShape = theSubShape->GetValue(); + + if (aMainShape.IsNull() || aSubShape.IsNull()) return -1; + + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aMainShape, anIndices); + if (anIndices.Contains(aSubShape)) { + SetErrorCode(OK); + return anIndices.FindIndex(aSubShape); + } + + return -1; +} + +//============================================================================= +/*! + * GetTopologyIndex + */ +//============================================================================= +Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape, + Handle(GEOM_Object) theSubShape) +{ + SetErrorCode(OK); + + TopoDS_Shape aMainShape = theMainShape->GetValue(); TopoDS_Shape aSubShape = theSubShape->GetValue(); if (aMainShape.IsNull() || aSubShape.IsNull()) { @@ -1387,7 +1739,7 @@ Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes */ try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif int iType, nbTypes [TopAbs_SHAPE]; @@ -1438,6 +1790,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) if (theShape.IsNull()) return NULL; + /* //Add a new reversed object Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType()); @@ -1458,7 +1811,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) //Compute the sub-shape value try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif if (!GetSolver()->ComputeFunction(aFunction)) { @@ -1477,6 +1830,21 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) << " = geompy.ChangeOrientation(" << theShape << ")"; SetErrorCode(OK); + */ + + Handle(GEOM_Object) aReversed; + + GEOM_Engine* anEngine = GetEngine(); + //GEOMImpl_Gen* aGen = dynamic_cast(anEngine); + GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine; + + if (aGen) { + GEOMImpl_IHealingOperations* anIHealingOperations = + aGen->GetIHealingOperations(GetDocID()); + aReversed = anIHealingOperations->ChangeOrientationCopy(theShape); + SetErrorCode(anIHealingOperations->GetErrorCode()); + } + return aReversed; } @@ -1683,7 +2051,21 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes // Make a Python command anAsciiList.Trunc(anAsciiList.Length() - 1); - GEOM::TPythonDump pd (aMainShape, /*append=*/true); + // IPAL22904: TC6.5.0: order of python commands is wrong after dump study + Handle(TColStd_HSequenceOfTransient) anObjects = new TColStd_HSequenceOfTransient; + for( it = theShapes.begin(); it != theShapes.end(); it++ ) + { + Handle(GEOM_Object) anObj = *it; + if( !anObj.IsNull() ) + anObjects->Append( anObj ); + } + + // Get the function of the latest published object + Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast( anObjects )->GetLastFunction(); + if( aFunction.IsNull() ) // just in case + aFunction = aMainShape; + + GEOM::TPythonDump pd (aFunction, /*append=*/true); pd << "[" << anAsciiList.ToCString() << "] = geompy.GetSharedShapesMulti(["; @@ -1815,12 +2197,12 @@ Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape //======================================================================= //function : getShapesOnBoxIDs /*! - * \brief Find IDs of subshapes complying with given status about surface - * \param theBox - the box to check state of subshapes against + * \brief Find IDs of sub-shapes complying with given status about surface + * \param theBox - the box to check state of sub-shapes against * \param theShape - the shape to explore - * \param theShapeType - type of subshape of theShape + * \param theShapeType - type of sub-shape of theShape * \param theState - required state - * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes + * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes */ //======================================================================= Handle(TColStd_HSequenceOfInteger) @@ -1896,12 +2278,12 @@ Handle(TColStd_HSequenceOfInteger) //======================================================================= //function : GetShapesOnBoxIDs /*! - * \brief Find subshapes complying with given status about surface - * \param theBox - the box to check state of subshapes against + * \brief Find sub-shapes complying with given status about surface + * \param theBox - the box to check state of sub-shapes against * \param theShape - the shape to explore - * \param theShapeType - type of subshape of theShape + * \param theShapeType - type of sub-shape of theShape * \param theState - required state - * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes + * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes */ //======================================================================= Handle(TColStd_HSequenceOfInteger) @@ -1910,7 +2292,7 @@ Handle(TColStd_HSequenceOfInteger) const Standard_Integer theShapeType, GEOMAlgo_State theState) { - // Find subshapes ids + // Find sub-shapes ids Handle(TColStd_HSequenceOfInteger) aSeqOfIDs = getShapesOnBoxIDs (theBox, theShape, theShapeType, theState); if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 ) @@ -1934,12 +2316,12 @@ Handle(TColStd_HSequenceOfInteger) //======================================================================= //function : GetShapesOnBox /*! - * \brief Find subshapes complying with given status about surface - * \param theBox - the box to check state of subshapes against + * \brief Find sub-shapes complying with given status about surface + * \param theBox - the box to check state of sub-shapes against * \param theShape - the shape to explore - * \param theShapeType - type of subshape of theShape + * \param theShapeType - type of sub-shape of theShape * \param theState - required state - * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes + * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes */ //======================================================================= Handle(TColStd_HSequenceOfTransient) @@ -1948,7 +2330,7 @@ Handle(TColStd_HSequenceOfTransient) const Standard_Integer theShapeType, GEOMAlgo_State theState) { - // Find subshapes ids + // Find sub-shapes ids Handle(TColStd_HSequenceOfInteger) aSeqOfIDs = getShapesOnBoxIDs (theBox, theShape, theShapeType, theState); if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 ) @@ -1980,12 +2362,12 @@ Handle(TColStd_HSequenceOfTransient) //======================================================================= //function : getShapesOnShapeIDs /*! - * \brief Find IDs of subshapes complying with given status about surface - * \param theCheckShape - the shape to check state of subshapes against + * \brief Find IDs of sub-shapes complying with given status about surface + * \param theCheckShape - the shape to check state of sub-shapes against * \param theShape - the shape to explore - * \param theShapeType - type of subshape of theShape + * \param theShapeType - type of sub-shape of theShape * \param theState - required state - * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes + * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes */ //======================================================================= Handle(TColStd_HSequenceOfInteger) @@ -2067,12 +2449,12 @@ Handle(TColStd_HSequenceOfInteger) //======================================================================= //function : GetShapesOnShapeIDs /*! - * \brief Find subshapes complying with given status about surface - * \param theCheckShape - the shape to check state of subshapes against + * \brief Find sub-shapes complying with given status about surface + * \param theCheckShape - the shape to check state of sub-shapes against * \param theShape - the shape to explore - * \param theShapeType - type of subshape of theShape + * \param theShapeType - type of sub-shape of theShape * \param theState - required state - * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes + * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes */ //======================================================================= Handle(TColStd_HSequenceOfInteger) @@ -2107,12 +2489,12 @@ Handle(TColStd_HSequenceOfInteger) //======================================================================= //function : GetShapesOnShape /*! - * \brief Find subshapes complying with given status about surface - * \param theCheckShape - the shape to check state of subshapes against + * \brief Find sub-shapes complying with given status about surface + * \param theCheckShape - the shape to check state of sub-shapes against * \param theShape - the shape to explore - * \param theShapeType - type of subshape of theShape + * \param theShapeType - type of sub-shape of theShape * \param theState - required state - * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes + * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes */ //======================================================================= Handle(TColStd_HSequenceOfTransient) @@ -2205,12 +2587,12 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound //======================================================================= //function : getShapesOnSurfaceIDs /*! - * \brief Find IDs of subshapes complying with given status about surface - * \param theSurface - the surface to check state of subshapes against + * \brief Find IDs of sub-shapes complying with given status about surface + * \param theSurface - the surface to check state of sub-shapes against * \param theShape - the shape to explore - * \param theShapeType - type of subshape of theShape + * \param theShapeType - type of sub-shape of theShape * \param theState - required state - * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes + * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes */ //======================================================================= Handle(TColStd_HSequenceOfInteger) @@ -2231,7 +2613,7 @@ Handle(TColStd_HSequenceOfInteger) // Compute tolerance Standard_Real T, VertMax = -RealLast(); try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 +#if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; #endif for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) { @@ -2348,13 +2730,13 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations:: //======================================================================= //function : getShapesOnSurface /*! - * \brief Find subshapes complying with given status about surface - * \param theSurface - the surface to check state of subshapes against + * \brief Find sub-shapes complying with given status about surface + * \param theSurface - the surface to check state of sub-shapes against * \param theShape - the shape to explore - * \param theShapeType - type of subshape of theShape + * \param theShapeType - type of sub-shape of theShape * \param theState - required state * \param theShapeEntries - outgoing entries like "entry1, entry2, ..." - * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes + * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes */ //======================================================================= Handle(TColStd_HSequenceOfTransient) @@ -2364,7 +2746,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMAlgo_State theState, TCollection_AsciiString & theShapeEntries) { - // Find subshapes ids + // Find sub-shapes ids Handle(TColStd_HSequenceOfInteger) aSeqOfIDs = getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState); if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 ) @@ -2950,15 +3332,15 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphere //======================================================================= //function : getShapesOnQuadrangleIDs /*! - * \brief Find IDs of subshapes complying with given status about quadrangle + * \brief Find IDs of sub-shapes complying with given status about quadrangle * \param theShape - the shape to explore - * \param theShapeType - type of subshape of theShape + * \param theShapeType - type of sub-shape of theShape * \param theTopLeftPoint - top left quadrangle corner * \param theTopRigthPoint - top right quadrangle corner * \param theBottomLeftPoint - bottom left quadrangle corner * \param theBottomRigthPoint - bottom right quadrangle corner * \param theState - required state - * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes + * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes */ //======================================================================= Handle(TColStd_HSequenceOfInteger) @@ -3076,15 +3458,15 @@ Handle(TColStd_HSequenceOfInteger) //======================================================================= //function : GetShapesOnQuadrangle /*! - * \brief Find subshapes complying with given status about quadrangle + * \brief Find sub-shapes complying with given status about quadrangle * \param theShape - the shape to explore - * \param theShapeType - type of subshape of theShape + * \param theShapeType - type of sub-shape of theShape * \param theTopLeftPoint - top left quadrangle corner * \param theTopRigthPoint - top right quadrangle corner * \param theBottomLeftPoint - bottom left quadrangle corner * \param theBottomRigthPoint - bottom right quadrangle corner * \param theState - required state - * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes + * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes */ //======================================================================= Handle(TColStd_HSequenceOfTransient) @@ -3137,15 +3519,15 @@ Handle(TColStd_HSequenceOfTransient) //======================================================================= //function : GetShapesOnQuadrangleIDs /*! - * \brief Find IDs of subshapes complying with given status about quadrangle + * \brief Find IDs of sub-shapes complying with given status about quadrangle * \param theShape - the shape to explore - * \param theShapeType - type of subshape of theShape + * \param theShapeType - type of sub-shape of theShape * \param theTopLeftPoint - top left quadrangle corner * \param theTopRigthPoint - top right quadrangle corner * \param theBottomLeftPoint - bottom left quadrangle corner * \param theBottomRigthPoint - bottom right quadrangle corner * \param theState - required state - * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes + * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes */ //======================================================================= Handle(TColStd_HSequenceOfInteger) @@ -3392,29 +3774,28 @@ namespace { } return defaultNorm; } +} - //================================================================================ - /*! - * \brief Return type of shape for explode. In case of compound it will be a type of sub shape. - */ - //================================================================================ - - TopAbs_ShapeEnum GetTypeOfSimplePart (const TopoDS_Shape& theShape) - { - TopAbs_ShapeEnum aType = theShape.ShapeType(); - if (aType == TopAbs_VERTEX) return TopAbs_VERTEX; - else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE; - else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE; - else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID; - else if (aType == TopAbs_COMPOUND) { - // Only the iType of the first shape in the compound is taken into account - TopoDS_Iterator It (theShape, Standard_False, Standard_False); - if (It.More()) { - return GetTypeOfSimplePart(It.Value()); - } +//================================================================================ +/*! + * \brief Return type of shape for explode. In case of compound it will be a type of sub-shape. + */ +//================================================================================ +TopAbs_ShapeEnum GEOMImpl_IShapesOperations::GetTypeOfSimplePart (const TopoDS_Shape& theShape) +{ + TopAbs_ShapeEnum aType = theShape.ShapeType(); + if (aType == TopAbs_VERTEX) return TopAbs_VERTEX; + else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE; + else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE; + else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID; + else if (aType == TopAbs_COMPOUND) { + // Only the iType of the first shape in the compound is taken into account + TopoDS_Iterator It (theShape, Standard_False, Standard_False); + if (It.More()) { + return GetTypeOfSimplePart(It.Value()); } - return TopAbs_SHAPE; } + return TopAbs_SHAPE; } //============================================================================= @@ -3449,6 +3830,177 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) TopTools_IndexedMapOfShape aWhereIndices; TopExp::MapShapes(aWhere, aWhereIndices); + TopAbs_ShapeEnum iType = TopAbs_SOLID; + Standard_Real dl_l = 1e-3; + Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass; + Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; + Bnd_Box BoundingBox; + gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2]; + GProp_GProps aProps; + + // Find the iType of the aWhat shape + iType = GetTypeOfSimplePart(aWhat); + if (iType == TopAbs_SHAPE) { + SetErrorCode("Error: An attempt to extract a shape of not supported type."); + return NULL; + } + + TopExp_Explorer Exp_aWhat ( aWhat, iType ); + TopExp_Explorer Exp_aWhere ( aWhere, iType ); + TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE ); + + // Find the shortest edge in theShapeWhere shape + BRepBndLib::Add(aWhere, BoundingBox); + BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + min_l = fabs(aXmax - aXmin); + if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin); + if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin); + min_l /= dl_l; + // Mantis issue 0020908 BEGIN + if (!Exp_Edge.More()) { + min_l = Precision::Confusion(); + } + // Mantis issue 0020908 END + for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) { + TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX); + for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) { + aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) ); + tab_Pnt[nbVertex] = aPnt; + } + if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) { + BRepGProp::LinearProperties(Exp_Edge.Current(), aProps); + if ( aProps.Mass() < min_l ) min_l = aProps.Mass(); + } + } + + // Compute tolerances + Tol_0D = dl_l; + Tol_1D = dl_l * min_l; + Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l); + Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) ); + + if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion(); + if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion(); + if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion(); + if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion(); + + Tol_Mass = Tol_3D; + if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D; + else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D; + else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D; + + // Searching for the sub-shapes inside the ShapeWhere shape + GEOMAlgo_GetInPlace aGIP; + aGIP.SetTolerance(Tol_1D); + aGIP.SetTolMass(Tol_Mass); + aGIP.SetTolCG(Tol_1D); + + aGIP.SetArgument(aWhat); + aGIP.SetShapeWhere(aWhere); + + aGIP.Perform(); + int iErr = aGIP.ErrorStatus(); + if (iErr) { + SetErrorCode("Error in GEOMAlgo_GetInPlace"); + return NULL; + } + + // aGIP.IsFound() returns true only when the whole theShapeWhat + // is found (as one shape or several parts). But we are also interested + // in the partial result, that is why this check is commented. + //if (!aGIP.IsFound()) { + // SetErrorCode(NOT_FOUND_ANY); + // return NULL; + //} + + const TopTools_DataMapOfShapeListOfShape& aDMSLS = aGIP.Images(); + if (!aDMSLS.IsBound(aWhat)) { + SetErrorCode(NOT_FOUND_ANY); + return NULL; + } + + // the list of shapes aLSA contains the shapes + // of the Shape For Search that corresponds + // to the Argument aWhat + const TopTools_ListOfShape& aLSA = aDMSLS.Find(aWhat); + if (aLSA.Extent() == 0) { + SetErrorCode(NOT_FOUND_ANY); // Not found any Results + return NULL; + } + + Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent()); + TopTools_ListIteratorOfListOfShape anIterModif (aLSA); + for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) { + if (aWhereIndices.Contains(anIterModif.Value())) { + aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value())); + } + else { + SetErrorCode("Error: wrong sub-shape returned"); + return NULL; + } + } + + //Add a new object + Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray); + if (aResult.IsNull()) { + SetErrorCode("Error in algorithm: result found, but cannot be returned."); + return NULL; + } + + if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) { + //Set a GROUP type + aResult->SetType(GEOM_GROUP); + + //Set a sub-shape type + TopoDS_Shape aFirstFound = aLSA.First(); + TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType(); + + TDF_Label aFreeLabel = aResult->GetFreeLabel(); + TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType); + } + + //Make a Python command + Handle(GEOM_Function) aFunction = aResult->GetFunction(1); + + GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace(" + << theShapeWhere << ", " << theShapeWhat << ", True)"; + + SetErrorCode(OK); + return aResult; +} + +//============================================================================= +/*! + * case GetInPlaceOld: + * default: + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere, + Handle(GEOM_Object) theShapeWhat) +{ + SetErrorCode(KO); + + if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL; + + TopoDS_Shape aWhere = theShapeWhere->GetValue(); + TopoDS_Shape aWhat = theShapeWhat->GetValue(); + TopoDS_Shape aPntShape; + TopoDS_Vertex aVertex; + + if (aWhere.IsNull() || aWhat.IsNull()) { + SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null."); + return NULL; + } + + Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction(); + if (aWhereFunction.IsNull()) { + SetErrorCode("Error: aWhereFunction is Null."); + return NULL; + } + + TopTools_IndexedMapOfShape aWhereIndices; + TopExp::MapShapes(aWhere, aWhereIndices); + TColStd_ListOfInteger aModifiedList; Standard_Integer aWhereIndex; Handle(TColStd_HArray1OfInteger) aModifiedArray; @@ -3584,7 +4136,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) if ( isFound && iType == TopAbs_FACE ) { // check normals at pOnWhat and pOnWhere - const double angleTol = PI/180.; + const double angleTol = M_PI/180.; gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance); gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance); if ( normToWhat * normToWhere < 0 ) @@ -3623,11 +4175,11 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) return NULL; } - if (aModifiedArray->Length() > 1) { + if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) { //Set a GROUP type aResult->SetType(GEOM_GROUP); - //Set a sub shape type + //Set a sub-shape type TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1)); TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType(); @@ -3639,7 +4191,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) Handle(GEOM_Function) aFunction = aResult->GetFunction(1); GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace(" - << theShapeWhere << ", " << theShapeWhat << ")"; + << theShapeWhere << ", " << theShapeWhat << ", False)"; SetErrorCode(OK); return aResult; @@ -3696,7 +4248,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory //Set a GROUP type aResult->SetType(GEOM_GROUP); - //Set a sub shape type + //Set a sub-shape type TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1)); TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType(); @@ -3714,6 +4266,106 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory return aResult; } +//======================================================================= +//function : ShapeToDouble +//purpose : used by CompareShapes::operator() +//======================================================================= +std::pair ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting) +{ + // Computing of CentreOfMass + gp_Pnt GPoint; + double Len; + + if (S.ShapeType() == TopAbs_VERTEX) { + GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S)); + Len = (double)S.Orientation(); + } + else { + GProp_GProps GPr; + // BEGIN: fix for Mantis issue 0020842 + if (isOldSorting) { + BRepGProp::LinearProperties(S, GPr); + } + else { + if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) { + BRepGProp::LinearProperties(S, GPr); + } + else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) { + BRepGProp::SurfaceProperties(S, GPr); + } + else { + BRepGProp::VolumeProperties(S, GPr); + } + } + // END: fix for Mantis issue 0020842 + GPoint = GPr.CentreOfMass(); + Len = GPr.Mass(); + } + + double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9; + return std::make_pair(dMidXYZ, Len); +} + +//======================================================================= +//function : CompareShapes::operator() +//purpose : used by std::sort(), called from SortShapes() +//======================================================================= +bool GEOMImpl_IShapesOperations::CompareShapes::operator()(const TopoDS_Shape& theShape1, + const TopoDS_Shape& theShape2) +{ + if (!myMap.IsBound(theShape1)) { + myMap.Bind(theShape1, ShapeToDouble(theShape1, myIsOldSorting)); + } + + if (!myMap.IsBound(theShape2)) { + myMap.Bind(theShape2, ShapeToDouble(theShape2, myIsOldSorting)); + } + + std::pair val1 = myMap.Find(theShape1); + std::pair val2 = myMap.Find(theShape2); + + double tol = Precision::Confusion(); + bool exchange = Standard_False; + + double dMidXYZ = val1.first - val2.first; + if (dMidXYZ >= tol) { + exchange = Standard_True; + } + else if (Abs(dMidXYZ) < tol) { + double dLength = val1.second - val2.second; + if (dLength >= tol) { + exchange = Standard_True; + } + else if (Abs(dLength) < tol && theShape1.ShapeType() <= TopAbs_FACE) { + // PAL17233 + // equal values possible on shapes such as two halves of a sphere and + // a membrane inside the sphere + Bnd_Box box1,box2; + BRepBndLib::Add(theShape1, box1); + if (!box1.IsVoid()) { + BRepBndLib::Add(theShape2, box2); + Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent(); + if (dSquareExtent >= tol) { + exchange = Standard_True; + } + else if (Abs(dSquareExtent) < tol) { + Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2; + box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + val1 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9; + box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + val2 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9; + if ((val1 - val2) >= tol) { + exchange = Standard_True; + } + } + } + } + } + + //return val1 < val2; + return !exchange; +} + //======================================================================= //function : SortShapes //purpose : @@ -3721,6 +4373,26 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL, const Standard_Boolean isOldSorting) { +#ifdef STD_SORT_ALGO + std::vector aShapesVec; + aShapesVec.reserve(SL.Extent()); + + TopTools_ListIteratorOfListOfShape it (SL); + for (; it.More(); it.Next()) { + aShapesVec.push_back(it.Value()); + } + SL.Clear(); + + CompareShapes shComp (isOldSorting); + std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp); + //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp); + + std::vector::const_iterator anIter = aShapesVec.begin(); + for (; anIter != aShapesVec.end(); ++anIter) { + SL.Append(*anIter); + } +#else + // old implementation Standard_Integer MaxShapes = SL.Extent(); TopTools_Array1OfShape aShapes (1,MaxShapes); TColStd_Array1OfInteger OrderInd(1,MaxShapes); @@ -3762,8 +4434,7 @@ void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL, GPoint = GPr.CentreOfMass(); Length.SetValue(Index, GPr.Mass()); } - MidXYZ.SetValue(Index, - GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9); + MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9); //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl; } @@ -3830,6 +4501,7 @@ void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL, for (Index=1; Index <= MaxShapes; Index++) SL.Append( aShapes( OrderInd(Index) )); +#endif } //======================================================================= @@ -4241,3 +4913,108 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object return aResult; } + + +//======================================================================= +//function : GetSameIDs +//purpose : +//======================================================================= +Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs + (const Handle(GEOM_Object)& theShapeWhere, + const Handle(GEOM_Object)& theShapeWhat) +{ + SetErrorCode(KO); + if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL; + + TopoDS_Shape aWhere = theShapeWhere->GetValue(); + TopoDS_Shape aWhat = theShapeWhat->GetValue(); + + if (aWhere.IsNull() || aWhat.IsNull()) return NULL; + + TopTools_ListOfShape listShape; + TopTools_MapOfShape aMap; + + if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) { + TopoDS_Iterator It (aWhat, Standard_True, Standard_True); + if (It.More()) aWhat = It.Value(); + It.Next(); + if (It.More()) { + SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument"); + return NULL; + } + } + + switch (aWhat.ShapeType()) { + case TopAbs_VERTEX: { + gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat)); + TopExp_Explorer E(aWhere, TopAbs_VERTEX); + for(; E.More(); E.Next()) { + if(!aMap.Add(E.Current())) continue; + gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current())); + if(P.Distance(P2) <= MAX_TOLERANCE) { + listShape.Append(E.Current()); + } + } + break; + } + case TopAbs_EDGE: { + TopoDS_Edge anEdge = TopoDS::Edge(aWhat); + TopExp_Explorer E(aWhere, TopAbs_EDGE); + for(; E.More(); E.Next()) { + if(!aMap.Add(E.Current())) continue; + if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) { + listShape.Append(E.Current()); + } + } + break; + } + case TopAbs_FACE: { + TopoDS_Face aFace = TopoDS::Face(aWhat); + TopExp_Explorer E(aWhere, TopAbs_FACE); + for(; E.More(); E.Next()) { + if(!aMap.Add(E.Current())) continue; + if(isSameFace(aFace, TopoDS::Face(E.Current()))) { + listShape.Append(E.Current()); + } + } + break; + } + case TopAbs_SOLID: { + TopoDS_Solid aSolid = TopoDS::Solid(aWhat); + TopExp_Explorer E(aWhere, TopAbs_SOLID); + for(; E.More(); E.Next()) { + if(!aMap.Add(E.Current())) continue; + if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) { + listShape.Append(E.Current()); + } + } + break; + } + default: + return NULL; + } + + if ( !listShape.IsEmpty() ) { + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aWhere, anIndices); + TopTools_ListIteratorOfListOfShape itSub (listShape); + Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger; + for (; itSub.More(); itSub.Next()) { + if (anIndices.Contains(itSub.Value())) + aSeq->Append(anIndices.FindIndex(itSub.Value())); + } + SetErrorCode(OK); + // The GetSameIDs() doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction(); + + // Make a Python command + GEOM::TPythonDump(aFunction) + << "listSameIDs = geompy.GetSameIDs(" + << theShapeWhere << ", " + << theShapeWhat << ")"; + return aSeq; + } else { + SetErrorCode(NOT_FOUND_ANY); + return NULL; + } +}