From fd7cf8e733d70e978888d2bfc9c87740084a521b Mon Sep 17 00:00:00 2001 From: skv Date: Thu, 11 Dec 2014 18:27:38 +0300 Subject: [PATCH] Refactoring GetInPlaceOld and GetInPlaceByHistory. Implement these methods in TransferData --- src/GEOMAlgo/CMakeLists.txt | 7 +- src/GEOMAlgo/FILES | 2 + src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx | 388 ++++++++++++++++++++ src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.hxx | 99 +++++ src/GEOMGUI/GEOM_msg_en.ts | 2 +- src/GEOMImpl/GEOMImpl_CopyDriver.cxx | 283 ++++++++++---- src/GEOMImpl/GEOMImpl_CopyDriver.hxx | 23 ++ src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 322 +++------------- src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 2 - 9 files changed, 776 insertions(+), 352 deletions(-) create mode 100644 src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx create mode 100644 src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.hxx diff --git a/src/GEOMAlgo/CMakeLists.txt b/src/GEOMAlgo/CMakeLists.txt index d85a789f1..0e30b8b26 100755 --- a/src/GEOMAlgo/CMakeLists.txt +++ b/src/GEOMAlgo/CMakeLists.txt @@ -23,6 +23,8 @@ INCLUDE_DIRECTORIES( ${CAS_INCLUDE_DIRS} ${KERNEL_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/src/GEOMUtils + ${PROJECT_SOURCE_DIR}/src/GEOM ${CMAKE_CURRENT_SOURCE_DIR} ) @@ -34,6 +36,7 @@ ADD_DEFINITIONS( # libraries to link to SET(_link_LIBRARIES ${CAS_KERNEL} ${CAS_TKBool} ${CAS_TKBO} ${CAS_TKMesh} + GEOMbasic GEOMUtils ${KERNEL_SALOMELocalTrace} ) @@ -60,6 +63,7 @@ SET(GEOMAlgo_HEADERS GEOMAlgo_FinderShapeOn2.hxx GEOMAlgo_FinderShapeOnQuad.hxx GEOMAlgo_GetInPlace.hxx + GEOMAlgo_GetInPlaceAPI.hxx GEOMAlgo_GlueAnalyser.hxx GEOMAlgo_GlueDetector.hxx GEOMAlgo_Gluer.hxx @@ -123,6 +127,7 @@ SET(GEOMAlgo_SOURCES GEOMAlgo_GetInPlace_1.cxx GEOMAlgo_GetInPlace_2.cxx GEOMAlgo_GetInPlace_3.cxx + GEOMAlgo_GetInPlaceAPI.cxx GEOMAlgo_GlueAnalyser.cxx GEOMAlgo_GlueDetector.cxx GEOMAlgo_Gluer.cxx @@ -142,7 +147,7 @@ SET(GEOMAlgo_SOURCES GEOMAlgo_ShapeInfoFiller.cxx GEOMAlgo_ShapeInfoFiller_1.cxx GEOMAlgo_ShapeSolid.cxx - GEOMAlgo_ShellSolid.cxx + GEOMAlgo_ShellSolid.cxx GEOMAlgo_SolidSolid.cxx GEOMAlgo_Splitter.cxx GEOMAlgo_StateCollector.cxx diff --git a/src/GEOMAlgo/FILES b/src/GEOMAlgo/FILES index 898eca027..aa1e05e72 100644 --- a/src/GEOMAlgo/FILES +++ b/src/GEOMAlgo/FILES @@ -54,6 +54,8 @@ GEOMAlgo_GetInPlace.cxx GEOMAlgo_GetInPlace_1.cxx GEOMAlgo_GetInPlace_2.cxx GEOMAlgo_GetInPlace_3.cxx +GEOMAlgo_GetInPlaceAPI.hxx +GEOMAlgo_GetInPlaceAPI.cxx GEOMAlgo_Splitter.hxx GEOMAlgo_Splitter.cxx GEOMAlgo_ShapeInfoFiller.hxx diff --git a/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx b/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx new file mode 100644 index 000000000..bc5c709af --- /dev/null +++ b/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.cxx @@ -0,0 +1,388 @@ +// Copyright (C) 2007-2014 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 +// +// 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, or (at your option) any later version. +// +// 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 +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: GEOMAlgo_GetInPlaceAPI.cxx +// Created: +// Author: Sergey KHROMOV + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//======================================================================= +//function : GetInPlaceOld +//purpose : +//======================================================================= +Standard_Integer GEOMAlgo_GetInPlaceAPI::GetInPlaceOld + (const TopoDS_Shape &theWhere, + const TopoDS_Shape &theWhat, + TopTools_ListOfShape &theShapesInPlace) +{ + theShapesInPlace.Clear(); + + if (theWhere.IsNull() || theWhat.IsNull()) { + // Error: aWhere and aWhat TopoDS_Shape are Null. + return 1; + } + + TopoDS_Shape aPntShape; + TopoDS_Vertex aVertex; + bool isFound = false; + TopAbs_ShapeEnum iType = TopAbs_SOLID; + //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.; + Standard_Real tab_aWhat[4], tab_aWhere[4]; + 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; + + iType = GEOMUtils::GetTypeOfSimplePart(theWhat); + if (iType == TopAbs_SHAPE) { + // Error: An attempt to extract a shape of not supported type. + return 2; + } + + TopExp_Explorer Exp_aWhat ( theWhat, iType ); + TopExp_Explorer Exp_aWhere ( theWhere, iType ); + TopExp_Explorer Exp_Edge ( theWhere, TopAbs_EDGE ); + + // Find the shortest edge in theShapeWhere shape + BRepBndLib::Add(theWhere, 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 + TopTools_MapOfShape map_aWhere; + for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) { + if (!map_aWhere.Add(Exp_aWhere.Current())) + continue; // skip repeated shape to avoid mass addition + GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt ); + for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) { + GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat ); + if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D ) + isFound = true; + else { + if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) { + aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape(); + aVertex = TopoDS::Vertex( aPntShape ); + BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() ); + BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() ); + if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() && + fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D ) + { + // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces" + // aVertex must be projected to the same point on Where and on What + gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1); + gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1); + isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D ); + if ( isFound && iType == TopAbs_FACE ) + { + // check normals at pOnWhat and pOnWhere + 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 ) + normToWhat.Reverse(); + isFound = ( normToWhat.Angle( normToWhere ) < angleTol ); + } + } + } + } + if ( isFound ) { + theShapesInPlace.Append(Exp_aWhere.Current()); + //aWhere_Mass += tab_aWhere[3]; + isFound = false; + break; + } + } + } + + if (theShapesInPlace.Extent() == 0) { + // Not found any Results + return 3; + } + + return 0; +} + +//======================================================================= +//function : GetNormal +//purpose : +//======================================================================= +gp_Vec GEOMAlgo_GetInPlaceAPI::GetNormal + (const TopoDS_Face &theFace, + const BRepExtrema_DistShapeShape &theExtrema) +{ + gp_Vec defaultNorm(1,0,0); // to have same normals on different faces + try { + // get UV at extrema point + Standard_Real u,v, f,l; + switch ( theExtrema.SupportTypeShape2(1) ) { + case BRepExtrema_IsInFace: { + theExtrema.ParOnFaceS2(1, u, v ); + break; + } + case BRepExtrema_IsOnEdge: { + TopoDS_Edge edge = TopoDS::Edge( theExtrema.SupportOnShape2(1)); + Handle(Geom2d_Curve) pcurve = + BRep_Tool::CurveOnSurface(edge, theFace, f,l); + + theExtrema.ParOnEdgeS2( 1, u ); + gp_Pnt2d uv = pcurve->Value( u ); + u = uv.Coord(1); + v = uv.Coord(2); + break; + } + case BRepExtrema_IsVertex: return defaultNorm; + } + // get derivatives + BRepAdaptor_Surface surface( theFace, false ); + gp_Vec du, dv; gp_Pnt p; + surface.D1( u, v, p, du, dv ); + + return du ^ dv; + + } catch (Standard_Failure ) { + } + return defaultNorm; +} + +//======================================================================= +//function : GetShapeProperties +//purpose : +//======================================================================= +void GEOMAlgo_GetInPlaceAPI::GetShapeProperties(const TopoDS_Shape &theShape, + Standard_Real theTab[], + gp_Pnt &theVertex) +{ + GProp_GProps aProps; + gp_Pnt aCenterMass; + Standard_Real aShapeSize; + + if (theShape.ShapeType() == TopAbs_VERTEX) { + aCenterMass = BRep_Tool::Pnt(TopoDS::Vertex(theShape)); + } else if (theShape.ShapeType() == TopAbs_EDGE) { + BRepGProp::LinearProperties(theShape, aProps); + } else if (theShape.ShapeType() == TopAbs_FACE) { + BRepGProp::SurfaceProperties(theShape, aProps); + } else { + BRepGProp::VolumeProperties(theShape, aProps); + } + + if (theShape.ShapeType() == TopAbs_VERTEX) { + aShapeSize = 1; + } else { + aCenterMass = aProps.CentreOfMass(); + aShapeSize = aProps.Mass(); + } + + theVertex = aCenterMass; + theTab[0] = theVertex.X(); + theTab[1] = theVertex.Y(); + theTab[2] = theVertex.Z(); + theTab[3] = aShapeSize; +} + +//======================================================================= +//function : GetInPlaceByHistory +//purpose : +//======================================================================= +Standard_Boolean GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory + (const Handle(GEOM_Function) &theWhereFunction, + const TopTools_IndexedMapOfShape &theWhereIndices, + const TopoDS_Shape &theWhat, + TopTools_ListOfShape &theShapesInPlace) +{ + if (theWhereFunction.IsNull() || theWhat.IsNull()) + return Standard_False; + + if (theWhereIndices.Contains(theWhat)) { + // entity was not changed by the operation + theShapesInPlace.Append(theWhat); + + return Standard_True; + } + + // try to find in history + TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False); + + // search in history for all argument shapes + Standard_Boolean isFound = Standard_False; + Standard_Boolean isGood = Standard_False; + + TDF_LabelSequence aLabelSeq; + theWhereFunction->GetDependency(aLabelSeq); + Standard_Integer nbArg = aLabelSeq.Length(); + + for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) { + + TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg); + + Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel); + TopoDS_Shape anArgumentShape = anArgumentObject->GetValue(); + + TopTools_IndexedMapOfShape anArgumentIndices; + TopExp::MapShapes(anArgumentShape, anArgumentIndices); + + if (anArgumentIndices.Contains(theWhat)) { + isFound = Standard_True; + Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat); + + // Find corresponding label in history + TDF_Label anArgumentHistoryLabel = + theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False); + if (anArgumentHistoryLabel.IsNull()) { + // Lost History of operation argument. Possibly, all its entities was removed. + isGood = Standard_True; + } + else { + TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False); + + if (aWhatHistoryLabel.IsNull()) { + // Removed entity ? Compound ? Compsolid ? Shell ? Wire + isGood = Standard_False; + } else { + Handle(TDataStd_IntegerArray) anIntegerArray; + if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) { + //Error: Empty modifications history for the sought shape. + isGood = Standard_False; + } + else { + isGood = Standard_True; + Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length(); + for (imod = 1; imod <= aModifLen; imod++) { + const Standard_Integer anIndex = + anIntegerArray->Array()->Value(imod); + + theShapesInPlace.Append(theWhereIndices.FindKey(anIndex)); + } + } + } + } + } + } + + isFound = isGood; + + if (!isFound) { + // try compound/compsolid/shell/wire element by element + Standard_Boolean isFoundAny = Standard_False; + TopTools_MapOfShape mapShape; + + if (theWhat.ShapeType() == TopAbs_COMPOUND || + theWhat.ShapeType() == TopAbs_COMPSOLID) { + // recursive processing of compound/compsolid + TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True); + for (; anIt.More(); anIt.Next()) { + if (mapShape.Add(anIt.Value())) { + TopoDS_Shape curWhat = anIt.Value(); + isFoundAny = GetInPlaceByHistory(theWhereFunction, theWhereIndices, curWhat, theShapesInPlace); + if (isFoundAny) isFound = Standard_True; + } + } + } + else if (theWhat.ShapeType() == TopAbs_SHELL) { + // try to replace a shell by its faces images + TopExp_Explorer anExp (theWhat, TopAbs_FACE); + for (; anExp.More(); anExp.Next()) { + if (mapShape.Add(anExp.Current())) { + TopoDS_Shape curWhat = anExp.Current(); + isFoundAny = GetInPlaceByHistory(theWhereFunction, theWhereIndices, curWhat, theShapesInPlace); + if (isFoundAny) isFound = Standard_True; + } + } + } + else if (theWhat.ShapeType() == TopAbs_WIRE) { + // try to replace a wire by its edges images + TopExp_Explorer anExp (theWhat, TopAbs_EDGE); + for (; anExp.More(); anExp.Next()) { + if (mapShape.Add(anExp.Current())) { + TopoDS_Shape curWhat = anExp.Current(); + isFoundAny = GetInPlaceByHistory(theWhereFunction, theWhereIndices, curWhat, theShapesInPlace); + if (isFoundAny) isFound = Standard_True; + } + } + } + else { + // Removed entity + } + } + + return isFound; +} diff --git a/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.hxx b/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.hxx new file mode 100644 index 000000000..43a8d6e90 --- /dev/null +++ b/src/GEOMAlgo/GEOMAlgo_GetInPlaceAPI.hxx @@ -0,0 +1,99 @@ +// Copyright (C) 2007-2014 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 +// +// 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, or (at your option) any later version. +// +// 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 +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File: GEOMAlgo_GetInPlaceAPI.hxx +// Created: +// Author: Sergey KHROMOV + +#ifndef _GEOMAlgo_GetInPlaceAPI_HeaderFile +#define _GEOMAlgo_GetInPlaceAPI_HeaderFile + + +#include + +class Handle_GEOM_Function; +class BRepExtrema_DistShapeShape; +class TopoDS_Face; +class TopoDS_Shape; +class TopTools_IndexedMapOfShape; +class TopTools_ListOfShape; + + +/** + * This is an API class for all GetInPlace algorithm. + * It facilitates using different GetInPlace algorithms: + * a new one(GEOMAlgo_GetInPlace), an old one and + * GetInPlaceByHistory. + */ +class GEOMAlgo_GetInPlaceAPI +{ + +public: + + /*! + * \brief Old implementation of GetInPlace algoritm. + * This method searches among sub shapes of the shape theWhere parts that are + * coincident with the shape theWhat. The result list of shape is returned as + * an output parameter. It returns the error code with the following possible + * values: + * 0 - Success; + * 1 - theWhere and/or theWhat TopoDS_Shape are Null; + * 2 - An attempt to extract a shape of not supported type; + * 3 - Not found any Results. + */ + Standard_EXPORT static Standard_Integer GetInPlaceOld + (const TopoDS_Shape &theWhere, + const TopoDS_Shape &theWhat, + TopTools_ListOfShape &theShapesInPlace); + + + /** + * \brief GetInPlaceBy history method implementation. + * Returns Standard_True if something is found. Warning: theShapesInPlace + * list is not cleared at first. + */ + Standard_EXPORT static Standard_Boolean GetInPlaceByHistory + (const Handle_GEOM_Function &theWhereFunction, + const TopTools_IndexedMapOfShape &theWhereIndices, + const TopoDS_Shape &theWhat, + TopTools_ListOfShape &theShapesInPlace); + +protected: + + /*! + * \brief Return normal to face at extrema point + */ + static gp_Vec GetNormal(const TopoDS_Face &theFace, + const BRepExtrema_DistShapeShape &theExtrema); + + /*! + * Return the global properties of the shape: center of mass and + * a size (length, area or volume depending on the shape type). + */ + static void GetShapeProperties(const TopoDS_Shape &theShape, + Standard_Real theTab[], + gp_Pnt &theVertex); + +}; + + + +#endif diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 43b4de74d..b08531396 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -7204,7 +7204,7 @@ Do you want to create new material? GEOM_TRANSFER_DATA_COPIED - The following data is copied: + The following data are copied: GEOM_TRANSFER_DATA_NAMES diff --git a/src/GEOMImpl/GEOMImpl_CopyDriver.cxx b/src/GEOMImpl/GEOMImpl_CopyDriver.cxx index bcca586a2..09ea9bba5 100644 --- a/src/GEOMImpl/GEOMImpl_CopyDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_CopyDriver.cxx @@ -27,6 +27,7 @@ #include "GEOM_Function.hxx" #include "GEOM_Object.hxx" #include "GEOMAlgo_GetInPlace.hxx" +#include "GEOMAlgo_GetInPlaceAPI.hxx" #include #include @@ -172,97 +173,26 @@ Standard_Integer GEOMImpl_CopyDriver::transferData(TFunction_Logbook& log) const TopoDS_Shape aShape2 = aRef2->GetValue(); const int aFindMethod = aTD.GetFindMethod(); TopTools_IndexedDataMapOfShapeListOfShape aMapSoDest; - Standard_Integer i; TopTools_IndexedMapOfShape anIndices1; - Standard_Integer aNbShapes; TopExp::MapShapes(aShape1, anIndices1); - aNbShapes = anIndices1.Extent(); switch (aFindMethod) { case TD_GET_IN_PLACE: - { - // Compute confusion tolerance. - Standard_Real aTolConf = Precision::Confusion(); - - for (i = 0; i < 2; ++i) { - TopExp_Explorer anExp(i == 0 ? aShape1 : aShape2, TopAbs_VERTEX); - - for (; anExp.More(); anExp.Next()) { - const TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current()); - const Standard_Real aTolVtx = BRep_Tool::Tolerance(aVtx); - - if (aTolVtx > aTolConf) { - aTolConf = aTolVtx; - } - } - } - - // Compute mass tolerance. - Bnd_Box aBoundingBox; - Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; - Standard_Real aMassTol; - - BRepBndLib::Add(aShape1, aBoundingBox); - BRepBndLib::Add(aShape2, aBoundingBox); - aBoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); - aMassTol = Max(aXmax - aXmin, aYmax - aYmin); - aMassTol = Max(aMassTol, aZmax - aZmin); - aMassTol *= aTolConf; - - // Searching for the sub-shapes inside the ShapeWhere shape - GEOMAlgo_GetInPlace aGIP; - aGIP.SetTolerance(aTolConf); - aGIP.SetTolMass(aMassTol); - aGIP.SetTolCG(aTolConf); - - aGIP.SetArgument(aShape1); - aGIP.SetShapeWhere(aShape2); - - aGIP.Perform(); - - int iErr = aGIP.ErrorStatus(); - - if (iErr) { - return 0; - } - - const GEOMAlgo_DataMapOfShapeMapOfShape &aShapesIn = aGIP.ShapesIn(); - const GEOMAlgo_DataMapOfShapeMapOfShape &aShapesOn = aGIP.ShapesOn(); - Standard_Integer j; - - for (j = 1; j <= aNbShapes; ++j) { - const TopoDS_Shape &aSource = anIndices1.FindKey(j); - TopTools_ListOfShape aListShapes2; - TopTools_MapOfShape aMapShapes2; - - for (i = 0; i < 2; ++i) { - const GEOMAlgo_DataMapOfShapeMapOfShape &aShapes2 = - i == 0 ? aShapesIn : aShapesOn; - - if (aShapes2.IsBound(aSource)) { - const TopTools_MapOfShape &aMapShapesDest = - aShapes2.Find(aSource); - TopTools_MapIteratorOfMapOfShape aMapIter(aMapShapesDest); - - for (; aMapIter.More(); aMapIter.Next()) { - const TopoDS_Shape &aShapeDest = aMapIter.Key(); - - if (aMapShapes2.Add(aShapeDest)) { - aListShapes2.Append(aShapeDest); - } - } - } - } - - if (!aListShapes2.IsEmpty()) { - aMapSoDest.Add(aSource, aListShapes2); - } - } + if (!getInPlace(aShape1, anIndices1, aShape2, aMapSoDest)) { + return 0; } break; case TD_GET_IN_PLACE_OLD: + if (!getInPlaceOld(aRef1, anIndices1, aShape2, aMapSoDest)) { + return 0; + } + break; case TD_GET_IN_PLACE_BY_HISTORY: + if (!getInPlaceByHistory(aRef1, anIndices1, aShape2, aRef2, aMapSoDest)) { + return 0; + } + break; default: return 0; } @@ -276,6 +206,8 @@ Standard_Integer GEOMImpl_CopyDriver::transferData(TFunction_Logbook& log) const new TColStd_HArray1OfInteger(1, NB_DATUM, 0); GEOMImpl_ITransferData aTD1(aRef1); GEOMImpl_ITransferData aTD2(aRef2); + Standard_Integer i; + Standard_Integer aNbShapes = anIndices1.Extent(); aDatumName->SetValue(DATUM_NAME_INDEX, "GEOM_TRANSFER_DATA_NAMES"); aDatumName->SetValue(DATUM_MATERIAL_INDEX, "GEOM_TRANSFER_DATA_MATERIALS"); @@ -334,6 +266,195 @@ Standard_Integer GEOMImpl_CopyDriver::transferData(TFunction_Logbook& log) const return 1; } +//================================================================================ +/*! + * \brief For each subshape of the source shape compute coinsident sub-shapes + * of the destination shape using GetInPlace method. + */ +//================================================================================ + +Standard_Boolean GEOMImpl_CopyDriver::getInPlace + (const TopoDS_Shape &theSourceShape, + const TopTools_IndexedMapOfShape &theSourceIndices, + const TopoDS_Shape &theDestinationShape, + TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const +{ + // Compute confusion tolerance. + Standard_Real aTolConf = Precision::Confusion(); + Standard_Integer i; + + for (i = 0; i < 2; ++i) { + TopExp_Explorer anExp + (i == 0 ? theSourceShape : theDestinationShape, TopAbs_VERTEX); + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current()); + const Standard_Real aTolVtx = BRep_Tool::Tolerance(aVtx); + + if (aTolVtx > aTolConf) { + aTolConf = aTolVtx; + } + } + } + + // Compute mass tolerance. + Bnd_Box aBoundingBox; + Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; + Standard_Real aMassTol; + + BRepBndLib::Add(theSourceShape, aBoundingBox); + BRepBndLib::Add(theDestinationShape, aBoundingBox); + aBoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + aMassTol = Max(aXmax - aXmin, aYmax - aYmin); + aMassTol = Max(aMassTol, aZmax - aZmin); + aMassTol *= aTolConf; + + // Searching for the sub-shapes inside the ShapeWhere shape + GEOMAlgo_GetInPlace aGIP; + aGIP.SetTolerance(aTolConf); + aGIP.SetTolMass(aMassTol); + aGIP.SetTolCG(aTolConf); + + aGIP.SetArgument(theSourceShape); + aGIP.SetShapeWhere(theDestinationShape); + + aGIP.Perform(); + + int iErr = aGIP.ErrorStatus(); + + if (iErr) { + return Standard_False; + } + + const GEOMAlgo_DataMapOfShapeMapOfShape &aShapesIn = aGIP.ShapesIn(); + const GEOMAlgo_DataMapOfShapeMapOfShape &aShapesOn = aGIP.ShapesOn(); + Standard_Integer j; + Standard_Integer aNbShapes = theSourceIndices.Extent(); + + for (j = 1; j <= aNbShapes; ++j) { + const TopoDS_Shape &aSource = theSourceIndices.FindKey(j); + TopTools_ListOfShape aListShapes2; + TopTools_MapOfShape aMapShapes2; + + for (i = 0; i < 2; ++i) { + const GEOMAlgo_DataMapOfShapeMapOfShape &aShapes2 = + i == 0 ? aShapesIn : aShapesOn; + + if (aShapes2.IsBound(aSource)) { + const TopTools_MapOfShape &aMapShapesDest = + aShapes2.Find(aSource); + TopTools_MapIteratorOfMapOfShape aMapIter(aMapShapesDest); + + for (; aMapIter.More(); aMapIter.Next()) { + const TopoDS_Shape &aShapeDest = aMapIter.Key(); + + if (aMapShapes2.Add(aShapeDest)) { + aListShapes2.Append(aShapeDest); + } + } + } + } + + if (!aListShapes2.IsEmpty()) { + theMapSourceDest.Add(aSource, aListShapes2); + } + } + + return Standard_True; +} + +//================================================================================ +/*! + * \brief For each subshape of the source shape compute coinsident sub-shapes + * of the destination shape using an old implementation + * of GetInPlace algorithm. + */ +//================================================================================ + +Standard_Boolean GEOMImpl_CopyDriver::getInPlaceOld + (const Handle(GEOM_Function) &theSourceRef, + const TopTools_IndexedMapOfShape &theSourceIndices, + const TopoDS_Shape &theDestinationShape, + TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const +{ + const Standard_Integer aNbShapes = theSourceIndices.Extent(); + Standard_Integer i; + Standard_Integer iErr; + TopTools_ListOfShape aModifiedList; + GEOMImpl_ITransferData aTDSource(theSourceRef); + + for (i = 1; i <= aNbShapes; ++i) { + const TopoDS_Shape &aSource = theSourceIndices.FindKey(i); + TCollection_AsciiString aName = aTDSource.GetName(aSource); + TCollection_AsciiString aMaterial = aTDSource.GetMaterial(aSource); + + if (aName.IsEmpty() && aMaterial.IsEmpty()) { + continue; + } + + // Call old GetInPlace. + iErr = GEOMAlgo_GetInPlaceAPI::GetInPlaceOld + (theDestinationShape, aSource, aModifiedList); + + if (iErr == 3) { + // Nothing is found. Skip. + continue; + } + + if (iErr) { + // Error. + return Standard_False; + } + + theMapSourceDest.Add(aSource, aModifiedList); + } + + return Standard_True; +} + +//================================================================================ +/*! + * \brief For each subshape of the source shape compute coinsident sub-shapes + * of the destination shape using GetInPlaceByHistory algorithm. + */ +//================================================================================ + +Standard_Boolean GEOMImpl_CopyDriver::getInPlaceByHistory + (const Handle(GEOM_Function) &theSourceRef, + const TopTools_IndexedMapOfShape &theSourceIndices, + const TopoDS_Shape &theDestinationShape, + const Handle(GEOM_Function) &theDestinationRef, + TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const +{ + const Standard_Integer aNbShapes = theSourceIndices.Extent(); + Standard_Integer i; + GEOMImpl_ITransferData aTDSource(theSourceRef); + TopTools_IndexedMapOfShape aDestIndices; + + TopExp::MapShapes(theDestinationShape, aDestIndices); + + for (i = 1; i <= aNbShapes; ++i) { + const TopoDS_Shape &aSource = theSourceIndices.FindKey(i); + TCollection_AsciiString aName = aTDSource.GetName(aSource); + TCollection_AsciiString aMaterial = aTDSource.GetMaterial(aSource); + + if (aName.IsEmpty() && aMaterial.IsEmpty()) { + continue; + } + + // Call GetInPlaceByHistory. + TopTools_ListOfShape aModifiedList; + const Standard_Boolean isFound = GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory + (theDestinationRef, aDestIndices, aSource, aModifiedList); + + if (isFound && !aModifiedList.IsEmpty()) { + theMapSourceDest.Add(aSource, aModifiedList); + } + } + + return Standard_True; +} + IMPLEMENT_STANDARD_HANDLE (GEOMImpl_CopyDriver,GEOM_BaseDriver); IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_CopyDriver,GEOM_BaseDriver); diff --git a/src/GEOMImpl/GEOMImpl_CopyDriver.hxx b/src/GEOMImpl/GEOMImpl_CopyDriver.hxx index f4a755b20..4541b6ffa 100644 --- a/src/GEOMImpl/GEOMImpl_CopyDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_CopyDriver.hxx @@ -58,10 +58,14 @@ #endif class TColStd_SequenceOfExtendedString; +class TopoDS_Shape; +class TopTools_IndexedDataMapOfShapeListOfShape; +class TopTools_IndexedMapOfShape; #include "GEOM_BaseDriver.hxx" + DEFINE_STANDARD_HANDLE( GEOMImpl_CopyDriver, GEOM_BaseDriver ); class GEOMImpl_CopyDriver : public GEOM_BaseDriver { @@ -87,6 +91,25 @@ private: Standard_Integer transferData(TFunction_Logbook& log) const; + Standard_Boolean getInPlace + (const TopoDS_Shape &theSourceShape, + const TopTools_IndexedMapOfShape &theSourceIndices, + const TopoDS_Shape &theDestinationShape, + TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const; + + Standard_Boolean getInPlaceOld + (const Handle(GEOM_Function) &theSourceShapeRef, + const TopTools_IndexedMapOfShape &theSourceIndices, + const TopoDS_Shape &theDestinationShape, + TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const; + + Standard_Boolean getInPlaceByHistory + (const Handle(GEOM_Function) &theSourceShapeRef, + const TopTools_IndexedMapOfShape &theSourceIndices, + const TopoDS_Shape &theDestinationShape, + const Handle(GEOM_Function) &theDestinationRef, + TopTools_IndexedDataMapOfShapeListOfShape &theMapSourceDest) const; + }; #endif diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index da8445efc..ac43bf39b 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -25,7 +25,7 @@ // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007 // Project : SALOME -#include +//#include #include "GEOMImpl_IShapesOperations.hxx" @@ -53,27 +53,28 @@ #include "GEOMAlgo_ClsfBox.hxx" #include "GEOMAlgo_ClsfSolid.hxx" -#include "GEOMAlgo_CoupleOfShapes.hxx" +//#include "GEOMAlgo_CoupleOfShapes.hxx" #include "GEOMAlgo_FinderShapeOn1.hxx" #include "GEOMAlgo_FinderShapeOnQuad.hxx" #include "GEOMAlgo_FinderShapeOn2.hxx" #include "GEOMAlgo_GetInPlace.hxx" +#include "GEOMAlgo_GetInPlaceAPI.hxx" #include "GEOMAlgo_GlueDetector.hxx" -#include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx" -#include "GEOMAlgo_ListOfCoupleOfShapes.hxx" +//#include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx" +//#include "GEOMAlgo_ListOfCoupleOfShapes.hxx" -#include +//#include #include -#include -#include +//#include +//#include #include #include #include -#include -#include -#include +//#include +//#include +//#include #include #include #include @@ -137,46 +138,6 @@ namespace { - //================================================================================ - /*! - * \brief Return normal to face at extrema point - */ - //================================================================================ - - gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema) - { - gp_Vec defaultNorm(1,0,0); // to have same normals on different faces - try { - // get UV at extrema point - Standard_Real u,v, f,l; - switch ( extrema.SupportTypeShape2(1) ) { - case BRepExtrema_IsInFace: { - extrema.ParOnFaceS2(1, u, v ); - break; - } - case BRepExtrema_IsOnEdge: { - TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1)); - Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l ); - extrema.ParOnEdgeS2( 1, u ); - gp_Pnt2d uv = pcurve->Value( u ); - u = uv.Coord(1); - v = uv.Coord(2); - break; - } - case BRepExtrema_IsVertex: return defaultNorm; - } - // get derivatives - BRepAdaptor_Surface surface( face, false ); - gp_Vec du, dv; gp_Pnt p; - surface.D1( u, v, p, du, dv ); - - return du ^ dv; - - } catch (Standard_Failure ) { - } - return defaultNorm; - } - void AddFlatSubShapes(const TopoDS_Shape& S, TopTools_ListOfShape& L, TopTools_MapOfShape& M) { if (S.ShapeType() != TopAbs_COMPOUND) { @@ -3954,41 +3915,6 @@ static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction, return isFound; } -//============================================================================= -/*! - * GetShapeProperties - */ -//============================================================================= -void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[], - gp_Pnt & aVertex ) -{ - GProp_GProps theProps; - gp_Pnt aCenterMass; - //TopoDS_Shape aPntShape; - Standard_Real aShapeSize; - - if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) ); - else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps); - else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps); - else BRepGProp::VolumeProperties(aShape, theProps); - - if (aShape.ShapeType() == TopAbs_VERTEX) - aShapeSize = 1; - else { - aCenterMass = theProps.CentreOfMass(); - aShapeSize = theProps.Mass(); - } - -// aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape(); -// aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) ); - aVertex = aCenterMass; - tab[0] = aVertex.X(); - tab[1] = aVertex.Y(); - tab[2] = aVertex.Z(); - tab[3] = aShapeSize; - return; -} - //============================================================================= /*! * case GetInPlace: @@ -4127,201 +4053,59 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) * default: */ //============================================================================= -Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere, - Handle(GEOM_Object) theShapeWhat) +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; + TopoDS_Shape aWhere = theShapeWhere->GetValue(); + TopoDS_Shape aWhat = theShapeWhat->GetValue(); + TopTools_ListOfShape aModifiedList; + const Standard_Integer iErr = + GEOMAlgo_GetInPlaceAPI::GetInPlaceOld(aWhere, aWhat, aModifiedList); - if (aWhere.IsNull() || aWhat.IsNull()) { - SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null."); - return NULL; - } + if (iErr) { + switch (iErr) { + case 1: + SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null."); + break; + case 2: + SetErrorCode + ("Error: An attempt to extract a shape of not supported type."); + break; + case 3: + SetErrorCode(NOT_FOUND_ANY); + break; + default: + SetErrorCode("Shape driver failed"); + break; + } - 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; - Handle(GEOM_Object) aResult; - - bool isFound = false; - TopAbs_ShapeEnum iType = TopAbs_SOLID; - //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.; - Standard_Real tab_aWhat[4], tab_aWhere[4]; - 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 - /* - if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX; - else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE; - else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE; - else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID; - else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) { - // Only the iType of the first shape in the compound is taken into account - TopoDS_Iterator It (aWhat, Standard_False, Standard_False); - if ( !It.More() ) { - SetErrorCode("Error: theShapeWhat is an empty COMPOUND."); - return NULL; - } - TopAbs_ShapeEnum compType = It.Value().ShapeType(); - if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX; - else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE; - else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE; - else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID; - } - else { - SetErrorCode("Error: An attempt to extract a shape of not supported type."); - return NULL; - } - */ - iType = GEOMUtils::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(); - - //if (Tol_1D > 1.0) Tol_1D = 1.0; - //if (Tol_2D > 1.0) Tol_2D = 1.0; - //if (Tol_3D > 1.0) Tol_3D = 1.0; + Handle(TColStd_HArray1OfInteger) aModifiedArray = + new TColStd_HArray1OfInteger (1, aModifiedList.Extent()); + TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList); + Standard_Integer imod; - 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; + for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) { + const Standard_Integer anIndex = + aWhereIndices.FindIndex(anIterModif.Value()); - // Compute the ShapeWhat Mass - /* - for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) { - if ( iType == TopAbs_VERTEX ) { - aWhat_Mass += 1; - continue; - } - else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps); - else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps); - else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps); - aWhat_Mass += aProps.Mass(); + aModifiedArray->SetValue(imod, anIndex); } - */ - - // Searching for the sub-shapes inside the ShapeWhere shape - TopTools_MapOfShape map_aWhere; - for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) { - if (!map_aWhere.Add(Exp_aWhere.Current())) - continue; // skip repeated shape to avoid mass addition - GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt ); - for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) { - GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat ); - if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D ) - isFound = true; - else { - if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) { - aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape(); - aVertex = TopoDS::Vertex( aPntShape ); - BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() ); - BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() ); - if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() && - fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D ) - { - // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces" - // aVertex must be projected to the same point on Where and on What - gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1); - gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1); - isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D ); - if ( isFound && iType == TopAbs_FACE ) - { - // check normals at pOnWhat and pOnWhere - 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 ) - normToWhat.Reverse(); - isFound = ( normToWhat.Angle( normToWhere ) < angleTol ); - } - } - } - } - if ( isFound ) { - aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current()); - aModifiedList.Append(aWhereIndex); - //aWhere_Mass += tab_aWhere[3]; - isFound = false; - break; - } - } - //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) - //break; - } - - if (aModifiedList.Extent() == 0) { // Not found any Results - SetErrorCode(NOT_FOUND_ANY); - return NULL; - } - - aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent()); - TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList); - for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) - aModifiedArray->SetValue(imod, anIterModif.Value()); //Add a new object - aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray); + Handle(GEOM_Object) aResult = + GetEngine()->AddSubShape(theShapeWhere, aModifiedArray); + if (aResult.IsNull()) { SetErrorCode("Error in algorithm: result found, but cannot be returned."); return NULL; @@ -4346,6 +4130,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Objec << theShapeWhere << ", " << theShapeWhat << ", False)"; SetErrorCode(OK); + return aResult; } @@ -4371,11 +4156,13 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory //Fill array of indices TopTools_IndexedMapOfShape aWhereIndices; + TopExp::MapShapes(aWhere, aWhereIndices); // process shape - TColStd_ListOfInteger aModifiedList; - bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList); + TopTools_ListOfShape aModifiedList; + bool isFound = GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory + (aWhereFunction, aWhereIndices, aWhat, aModifiedList); if (!isFound || aModifiedList.Extent() < 1) { SetErrorCode("Error: No history found for the sought shape or its sub-shapes."); @@ -4383,13 +4170,13 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory } Standard_Integer nbFound = aModifiedList.Extent(); - TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList); + TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList); if ( nbFound > 1 ) { // remove sub-shapes inappropriate for group creation TopAbs_ShapeEnum subType = TopAbs_SHAPE; while ( anIterModif.More() ) { - TopAbs_ShapeEnum type = aWhereIndices( anIterModif.Value() ).ShapeType(); + TopAbs_ShapeEnum type = anIterModif.Value().ShapeType(); bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE || type == TopAbs_FACE || type == TopAbs_SOLID ); if ( okForGroup ) { @@ -4414,7 +4201,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory new TColStd_HArray1OfInteger( 1, nbFound ); anIterModif.Initialize(aModifiedList); for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) - aModifiedArray->SetValue(imod, anIterModif.Value()); + aModifiedArray->SetValue + (imod, aWhereIndices.FindIndex(anIterModif.Value())); //Add a new object Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray); diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index dca4233a9..68543ebec 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -297,8 +297,6 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations Handle(GEOM_Object) theCenter, const Standard_Real theRadius); - void GetShapeProperties(const TopoDS_Shape aShape, Standard_Real propertiesArray[], gp_Pnt & aPnt); - Standard_EXPORT Handle(GEOM_Object) GetInPlace (Handle(GEOM_Object) theShapeWhere, Handle(GEOM_Object) theShapeWhat); -- 2.39.2