NPAL16588: Bug in GetInPlace method.

This commit is contained in:
jfa 2007-07-25 07:07:07 +00:00
parent 95d4ca81b7
commit b2926171f3
7 changed files with 342 additions and 14 deletions

View File

@ -1311,7 +1311,7 @@ module GEOM
in shape_state theState);
/*!
* Get sub-shape(s) of theShapeWhere, which are
* Get sub-shape(s) of \a theShapeWhere, which are
* coincident with \a theShapeWhat or could be a part of it.
* \param theShapeWhere Shape to find sub-shapes of.
* \param theShapeWhat Shape, specifying what to find.
@ -1320,6 +1320,23 @@ module GEOM
GEOM_Object GetInPlace (in GEOM_Object theShapeWhere,
in GEOM_Object theShapeWhat);
/*!
* Get sub-shape(s) of \a theShapeWhere, which are
* coincident with \a theShapeWhat or could be a part of it.
*
* Implementation of this method is based on a saved history of an operation,
* produced \a theShapeWhere. The \a theShapeWhat must be among this operation's
* arguments (an argument shape or a sub-shape of an argument shape).
* The operation could be the Partition or one of boolean operations,
* performed on simple shapes (not on compounds).
*
* \param theShapeWhere Shape to find sub-shapes of.
* \param theShapeWhat Shape, specifying what to find.
* \return Group of all found sub-shapes or a single found sub-shape.
*/
GEOM_Object GetInPlaceByHistory (in GEOM_Object theShapeWhere,
in GEOM_Object theShapeWhat);
/*!
* Get sub-shape of theShapeWhere, which are
* coincident with \a theShapeWhat that can either SOLID, FACE, EDGE or VERTEX.

View File

@ -17,6 +17,11 @@
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : GEOMImpl_IShapesOperations.cxx
// Created :
// Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
// Project : SALOME
// $Header$
#include <Standard_Stream.hxx>
@ -111,6 +116,16 @@
#include <Standard_Failure.hxx>
#include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
// Includes added for GetInPlace algorithm improvement
#include <GEOMImpl_MeasureDriver.hxx>
#include <GEOMImpl_IMeasure.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepClass_FaceClassifier.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <Precision.hxx>
//=============================================================================
/*!
* constructor:
@ -2408,7 +2423,7 @@ Handle(TColStd_HSequenceOfInteger)
//=============================================================================
/*!
* GetInPlace
* GetInPlaceOfShape
*/
//=============================================================================
static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
@ -2530,7 +2545,182 @@ static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
return isFound;
}
Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
//=============================================================================
/*!
* GetShapeProperties
*/
//=============================================================================
void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
gp_Pnt & aVertex )
{
GProp_GProps SProps, VProps;
gp_Pnt aCenterMass;
TopoDS_Shape aPntShape;
Standard_Real aShapeSize;
BRepGProp::VolumeProperties(aShape, VProps);
aCenterMass = VProps.CentreOfMass();
aShapeSize = VProps.Mass();
if (aShape.ShapeType() == TopAbs_FACE) {
BRepGProp::SurfaceProperties(aShape, SProps);
aCenterMass = SProps.CentreOfMass();
aShapeSize = SProps.Mass();
}
aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
tab[0] = aVertex.X();
tab[1] = aVertex.Y();
tab[2] = aVertex.Z();
tab[3] = aShapeSize;
return;
}
//=============================================================================
/*!
* GetInPlace
*/
//=============================================================================
Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (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();
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;
Handle(GEOM_Object) aResult;
bool isFound = false;
Standard_Integer 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_1D, Tol_2D, Tol_3D, Tol_Mass;
gp_Pnt aPnt, aPnt_aWhat;
GProp_GProps aProps;
// 2D or 3D shapes
if ( aWhat.ShapeType() == TopAbs_COMPOUND ||
aWhat.ShapeType() == TopAbs_SHELL ||
aWhat.ShapeType() == TopAbs_COMPSOLID ) {
TopExp_Explorer Exp( aWhat, TopAbs_ShapeEnum( iType ) );
if ( ! Exp.More() ) iType = TopAbs_FACE;
}
else if ( aWhat.ShapeType() == TopAbs_FACE )
iType = TopAbs_FACE;
TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
// Find the shortest edge in theShapeWhere shape
for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
if ( ! nbEdge ) min_l = aProps.Mass();
if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
}
// Compute tolerances
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) );
Tol_Mass = Tol_3D;
if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
// Compute the ShapeWhat Mass
for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
if ( iType == TopAbs_SOLID ) BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
aWhat_Mass += aProps.Mass();
}
// Finding the Sub-ShapeWhere
for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
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) ) {
BRepClass3d_SolidClassifier SC_aWhere (Exp_aWhere.Current(), aPnt, Precision::Confusion());
BRepClass3d_SolidClassifier SC_aWhat (Exp_aWhat.Current(), aPnt, Precision::Confusion());
// Block construction 3D
if ( SC_aWhere.State() == TopAbs_IN && SC_aWhat.State() == TopAbs_IN ) isFound = true;
// Block construction 2D
else if ( SC_aWhere.State() == TopAbs_ON && SC_aWhat.State() == TopAbs_ON ) isFound = true;
}
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;
}
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);
if (aResult.IsNull()) {
SetErrorCode("Error in algorithm: result found, but cannot be returned.");
return NULL;
}
if (aModifiedArray->Length() > 1) {
//Set a GROUP type
aResult->SetType(GEOM_GROUP);
//Set a sub shape type
TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
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 << ")";
SetErrorCode(OK);
return aResult;
}
//=======================================================================
//function : GetInPlaceByHistory
//purpose :
//=======================================================================
Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
(Handle(GEOM_Object) theShapeWhere,
Handle(GEOM_Object) theShapeWhat)
{

View File

@ -17,7 +17,14 @@
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
//=============================================================================
// File : GEOMImpl_IShapesOperations.hxx
// Created :
// Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
// Project : SALOME
// Copyright : CEA 2003
// $Header$
//=============================================================================
#ifndef _GEOMImpl_IShapesOperations_HXX_
#define _GEOMImpl_IShapesOperations_HXX_
@ -32,6 +39,8 @@
#include <list>
#include <Handle_Geom_Surface.hxx>
#include <gp_Pnt.hxx>
class GEOM_Engine;
class Handle(GEOM_Object);
class Handle(TColStd_HArray1OfInteger);
@ -206,9 +215,14 @@ 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);
Standard_EXPORT Handle(GEOM_Object) GetInPlaceByHistory (Handle(GEOM_Object) theShapeWhere,
Handle(GEOM_Object) theShapeWhat);
/*!
* \brief Searches a shape equal to theWhat in the context of theWhere
* \param theShapeWhere - a context shap

View File

@ -1325,6 +1325,41 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::GetInPlace
return GetObject(anObject);
}
//=============================================================================
/*!
* GetInPlaceByHistory
*/
//=============================================================================
GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::GetInPlaceByHistory
(GEOM::GEOM_Object_ptr theShapeWhere,
GEOM::GEOM_Object_ptr theShapeWhat)
{
GEOM::GEOM_Object_var aGEOMObject;
//Set a not done flag
GetOperations()->SetNotDone();
if (theShapeWhere == NULL ||
theShapeWhat == NULL) return aGEOMObject._retn();
//Get the reference objects
Handle(GEOM_Object) aShapeWhere = GetOperations()->GetEngine()->GetObject
(theShapeWhere->GetStudyID(), theShapeWhere->GetEntry());
Handle(GEOM_Object) aShapeWhat = GetOperations()->GetEngine()->GetObject
(theShapeWhat->GetStudyID(), theShapeWhat->GetEntry());
if (aShapeWhere.IsNull() ||
aShapeWhat.IsNull()) return aGEOMObject._retn();
//Get Shapes in place of aShapeWhat
Handle(GEOM_Object) anObject =
GetOperations()->GetInPlaceByHistory(aShapeWhere, aShapeWhat);
if (!GetOperations()->IsDone() || anObject.IsNull())
return aGEOMObject._retn();
return GetObject(anObject);
}
//=============================================================================
/*!
* GetSame

View File

@ -176,6 +176,9 @@ class GEOM_IShapesOperations_i :
GEOM::GEOM_Object_ptr GetInPlace (GEOM::GEOM_Object_ptr theShapeWhere,
GEOM::GEOM_Object_ptr theShapeWhat);
GEOM::GEOM_Object_ptr GetInPlaceByHistory (GEOM::GEOM_Object_ptr theShapeWhere,
GEOM::GEOM_Object_ptr theShapeWhat);
GEOM::GEOM_Object_ptr GetSame (GEOM::GEOM_Object_ptr theShapeWhere,
GEOM::GEOM_Object_ptr theShapeWhat);

View File

@ -524,24 +524,72 @@ def TestOtherOperations (geompy, math):
geompy.UnionIDs(vertices_on_quad, vertices_on_quad_ids)
geompy.addToStudy(vertices_on_quad, "Group of vertices on Quadrangle F12")
# GetInPlace(theShapeWhere, theShapeWhat)
# Prepare arguments for GetInPlace and GetInPlaceByHistory
box5 = geompy.MakeBoxDXDYDZ(100, 100, 100)
box6 = geompy.MakeTranslation(box5, 50, 50, 0)
geompy.addToStudy(box5, "Box 5")
geompy.addToStudy(box6, "Box 6")
part = geompy.MakePartition([box5], [box6])
geompy.addToStudy(part, "Partitioned")
box5_faces = geompy.SubShapeAll(box5, geompy.ShapeType["FACE"])
box6_faces = geompy.SubShapeAll(box6, geompy.ShapeType["FACE"])
ifa = 1
for aface in box5_faces:
geompy.addToStudyInFather(box5, aface, "Face" + `ifa`)
ifa = ifa + 1
ifa = 1
for aface in box6_faces:
geompy.addToStudyInFather(box6, aface, "Face" + `ifa`)
ifa = ifa + 1
# GetInPlace(theShapeWhere, theShapeWhat)
ibb = 5
box_list = [box5, box6]
for abox in box_list:
geompy.addToStudy(abox, "Box " + `ibb`)
box_faces = geompy.SubShapeAll(abox, geompy.ShapeType["FACE"])
faces_list = [box5_faces, box6_faces]
for afaces in faces_list:
ifa = 1
for aface in box_faces:
geompy.addToStudyInFather(abox, aface, "Face" + `ifa`)
refl_box_face = geompy.GetInPlace(part, aface)
if refl_box_face is not None:
for aface in afaces:
if ibb == 6 and (ifa == 2 or ifa == 4):
# use IDL interface directly to avoid error message appearence in Python console
refl_box_face = geompy.ShapesOp.GetInPlace(part, aface)
if refl_box_face is not None:
geompy.addToStudyInFather(part, refl_box_face,
"Reflection of face " + `ifa` + " of box " + `ibb`)
error = "Result of GetInPlace must be NULL for face " + `ifa` + " of box " + `ibb`
raise RuntimeError, error
else:
# use geompy interface
refl_box_face = geompy.GetInPlace(part, aface)
geompy.addToStudyInFather(part, refl_box_face,
"Reflection of Face " + `ifa` + " of box " + `ibb`)
"Reflection of face " + `ifa` + " of box " + `ibb`)
ifa = ifa + 1
ibb = ibb + 1
# GetInPlaceByHistory(theShapeWhere, theShapeWhat)
part = geompy.MakePartition([box5], [box6])
geompy.addToStudy(part, "Partitioned")
ibb = 5
faces_list = [box5_faces, box6_faces]
for afaces in faces_list:
ifa = 1
for aface in afaces:
if ibb == 6 and (ifa == 2 or ifa == 4):
# use IDL interface directly to avoid error message appearence in Python console
refl_box_face = geompy.ShapesOp.GetInPlaceByHistory(part, aface)
if refl_box_face is not None:
geompy.addToStudyInFather(part, refl_box_face,
"Reflection of face " + `ifa` + " of box " + `ibb` + " (by history)")
error = "Result of GetInPlaceByHistory must be NULL for face " + `ifa` + " of box " + `ibb`
raise RuntimeError, error
else:
# use geompy interface
refl_box_face = geompy.GetInPlaceByHistory(part, aface)
geompy.addToStudyInFather(part, refl_box_face,
"Reflection of face " + `ifa` + " of box " + `ibb` + " (by history)")
ifa = ifa + 1
ibb = ibb + 1

View File

@ -1097,6 +1097,27 @@ def GetInPlace(theShapeWhere, theShapeWhat):
print "GetInPlace : ", ShapesOp.GetErrorCode()
return anObj
## Get sub-shape(s) of \a theShapeWhere, which are
# coincident with \a theShapeWhat or could be a part of it.
#
# Implementation of this method is based on a saved history of an operation,
# produced \a theShapeWhere. The \a theShapeWhat must be among this operation's
# arguments (an argument shape or a sub-shape of an argument shape).
# The operation could be the Partition or one of boolean operations,
# performed on simple shapes (not on compounds).
#
# @param theShapeWhere Shape to find sub-shapes of.
# @param theShapeWhat Shape, specifying what to find (must be in the
# building history of the ShapeWhere).
# @return Group of all found sub-shapes or a single found sub-shape.
#
# Example: see GEOM_TestOthers.py
def GetInPlaceByHistory(theShapeWhere, theShapeWhat):
anObj = ShapesOp.GetInPlaceByHistory(theShapeWhere, theShapeWhat)
if ShapesOp.IsDone() == 0:
print "GetInPlace : ", ShapesOp.GetErrorCode()
return anObj
## Get sub-shape of theShapeWhere, which is
# equal to \a theShapeWhat.
# @param theShapeWhere Shape to find sub-shape of.