0022686: [CEA 1268] Explode a shape into edges sorted in a row from a starting point

This commit is contained in:
skv 2015-01-14 16:43:10 +03:00 committed by vsr
parent 52713a9ee9
commit 48e895f1fa
8 changed files with 349 additions and 17 deletions

View File

@ -61,7 +61,7 @@
\until Scale4
\anchor swig_all_trsf_more
\until MakeOffset
\until MakeProjectionOnWire
\anchor swig_ChangeOrientation
\until ChangeOrientation
@ -69,11 +69,13 @@
\anchor swig_ExtractShapes
\until prism_edges
\until IDlist_f
\anchor swig_FilletChamfer
\until End of Local operations
\anchor swig_all_patterns
\until MultiRot2D
\until MultiRot2Ds
\anchor swig_all_measure
\until "CheckShape(Prism) = "
@ -91,6 +93,9 @@
\until nameS
\anchor swig_all_decompose
\until geompy.RestoreSubShapes(Partition1)
\anchor swig_GetSubShapeEdgeSorted
\until print "DONE"
*/

View File

@ -2516,6 +2516,15 @@ module GEOM
ListOfLong GetSameIDs (in GEOM_Object theShapeWhere,
in GEOM_Object theShapeWhat);
/*!
* \brief Explode a shape into edges sorted in a row from a starting point.
* \param theShape - the shape to be exploded on edges.
* \param theStartPoint - the starting point.
* \return Ordered list of edges sorted in a row from a starting point.
*/
ListOfGO GetSubShapeEdgeSorted (in GEOM_Object theShape,
in GEOM_Object theStartPoint);
};
// # GEOM_IBlocksOperations:

View File

@ -143,6 +143,46 @@
#include <BRepClass3d_SolidClassifier.hxx>
#include <Precision.hxx>
namespace
{
const double MAX_TOLERANCE = 1.e-7;
/**
* \brief Returns the vertex from theWhere shape that is coincident with
* theVertex.
*
* \param theWhere the shape where the coinsident vertex is searched.
* \param theVertex the vertex to be searched.
* \return the coincident vertex if it is found. Otherwise null object.
*/
static TopoDS_Vertex getSameVertex(const TopoDS_Shape &theWhere,
const TopoDS_Vertex &theVertex)
{
TopoDS_Vertex aResult;
gp_Pnt aPoint = BRep_Tool::Pnt(theVertex);
TopExp_Explorer anExp(theWhere, TopAbs_VERTEX);
TopTools_MapOfShape aMap;
for(; anExp.More(); anExp.Next()) {
const TopoDS_Shape &aLocalShape = anExp.Current();
if(!aMap.Add(aLocalShape)) {
continue;
}
TopoDS_Vertex aVertex = TopoDS::Vertex(aLocalShape);
gp_Pnt aPoint2 = BRep_Tool::Pnt(aVertex);
if(aPoint.Distance(aPoint2) <= MAX_TOLERANCE) {
aResult = aVertex;
break;
}
}
return aResult;
}
} // end of namespace
//=============================================================================
/*!
* constructor:
@ -2635,6 +2675,44 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
return aRes;
}
//=============================================================================
/*!
* GetSubShapeEdgeSorted
*/
//=============================================================================
Handle(TColStd_HSequenceOfTransient)
GEOMImpl_IShapesOperations::GetSubShapeEdgeSorted
(const Handle(GEOM_Object) &theShape,
const Handle(GEOM_Object) &theStartPoint)
{
// Get the sorted edges indices.
Handle(TColStd_HSequenceOfInteger) aSortedIDs =
getSubShapeEdgeSortedIDs(theShape, theStartPoint);
// Get object by indices.
TCollection_AsciiString anAsciiList;
Handle(TColStd_HSequenceOfTransient) aSeq =
getObjectsShapesOn(theShape, aSortedIDs, anAsciiList);
if (aSeq.IsNull() || aSeq->IsEmpty()) {
SetErrorCode("Empty sequence of edges");
return NULL;
}
// Make a Python command
Handle(GEOM_Object) anObj =
Handle(GEOM_Object)::DownCast(aSeq->Value(1));
Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
GEOM::TPythonDump(aFunction)
<< "[" << anAsciiList.ToCString() << "] = geompy.GetSubShapeEdgeSorted("
<< theShape << ", " << theStartPoint << ")";
SetErrorCode(OK);
return aSeq;
}
//=======================================================================
//function : getShapesOnSurfaceIDs
/*!
@ -2776,6 +2854,152 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
return aSeq;
}
//=============================================================================
/*!
* getSubShapeEdgeSortedIDs
*/
//=============================================================================
Handle(TColStd_HSequenceOfInteger)
GEOMImpl_IShapesOperations::getSubShapeEdgeSortedIDs
(const Handle(GEOM_Object) &theShape,
const Handle(GEOM_Object) &theStartPoint)
{
Handle(TColStd_HSequenceOfInteger) aResult;
if (theShape.IsNull() || theStartPoint.IsNull()) {
SetErrorCode("NULL GEOM object");
return aResult;
}
const TopoDS_Shape aShape = theShape->GetValue();
const TopoDS_Shape aStartPoint = theStartPoint->GetValue();
if (aShape.IsNull() || aStartPoint.IsNull()) {
SetErrorCode("NULL Shape");
return aResult;
}
if (aStartPoint.ShapeType() != TopAbs_VERTEX) {
SetErrorCode("Starting point is not a vertex");
return aResult;
}
TopExp_Explorer anExp(aShape, TopAbs_EDGE);
TopTools_MapOfShape aMapFence;
TopTools_ListOfShape anEdges;
for (; anExp.More(); anExp.Next()) {
const TopoDS_Shape &anEdge = anExp.Current();
if (aMapFence.Add(anEdge)) {
anEdges.Append(anEdge);
}
}
if (anEdges.IsEmpty()) {
SetErrorCode("Shape doesn't contain edges");
return aResult;
}
// Step 1: Sort edges
GEOMUtils::SortShapes(anEdges, Standard_False);
TopTools_ListIteratorOfListOfShape anIter(anEdges);
TopoDS_Vertex aV[2];
TopTools_DataMapOfShapeListOfShape aMapVE;
// Step 2: Fill the map vertex - list of edges.
for (; anIter.More(); anIter.Next()) {
TopoDS_Edge anEdge = TopoDS::Edge(anIter.Value());
TopExp::Vertices(anEdge, aV[0], aV[1]);
const Standard_Integer aNbV = aV[0].IsSame(aV[1]) ? 1 : 2;
Standard_Integer i;
for (i = 0; i < aNbV; ++i) {
if (aV[i].IsNull() == Standard_False) {
if (!aMapVE.IsBound(aV[i])) {
// There is no this vertex in the map.
aMapVE.Bind(aV[i], TopTools_ListOfShape());
}
// Add the edge to the list bound with the vertex aV[i].
TopTools_ListOfShape &aLEdges = aMapVE.ChangeFind(aV[i]);
aLEdges.Append(anEdge);
}
}
}
// Step 3: Find starting point in aMapVE.
TopoDS_Vertex aStartVtx = TopoDS::Vertex(aStartPoint);
if (!aMapVE.IsBound(aStartVtx)) {
aStartVtx = getSameVertex(aShape, aStartVtx);
if (aStartVtx.IsNull()) {
SetErrorCode("Invalid Starting point");
return aResult;
}
}
TopTools_IndexedMapOfShape anIndices;
TopTools_MapOfShape aMapVFence;
TopoDS_Shape aCurVtx = aStartVtx;
TopoDS_Edge aCurEdge =
TopoDS::Edge(aMapVE.Find(aCurVtx).First());
aResult = new TColStd_HSequenceOfInteger;
TopExp::MapShapes(aShape, anIndices);
// Step 4: Fill the list of sorted edges.
while (aMapVFence.Add(aCurVtx)) {
// Append the ID of the current edge to the list of sorted.
aResult->Append(anIndices.FindIndex(aCurEdge));
TopExp::Vertices(aCurEdge, aV[0], aV[1]);
// Get the next vertex.
if (aCurVtx.IsSame(aV[0])) {
if (aCurVtx.IsSame(aV[1])) {
// There is no next vertex.
break;
} else {
aCurVtx = aV[1];
}
} else {
aCurVtx = aV[0];
}
if (aCurVtx.IsNull()) {
// There is no next vertex.
break;
}
// Get the next edge.
const TopTools_ListOfShape &aLEdges = aMapVE.Find(aCurVtx);
TopTools_ListIteratorOfListOfShape anEIter(aLEdges);
for (; anEIter.More(); anEIter.Next()) {
const TopoDS_Shape &aLocalEdge = anEIter.Value();
if (aLocalEdge.IsNull() == Standard_False) {
if (!aCurEdge.IsSame(aLocalEdge)) {
aCurEdge = TopoDS::Edge(aLocalEdge);
break;
}
}
}
if (!anEIter.More()) {
// There is no next edge.
break;
}
}
return aResult;
}
//=======================================================================
//function : getShapesOnSurface
/*!
@ -4281,8 +4505,6 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
return aResult;
}
#define MAX_TOLERANCE 1.e-7
//=======================================================================
//function : isSameEdge
//purpose : Returns True if two edges coincide
@ -4534,17 +4756,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object
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) {
isFound = true;
aSubShape = E.Current();
break;
}
}
aSubShape = getSameVertex(aWhere, TopoDS::Vertex(aWhat));
isFound = !aSubShape.IsNull();
break;
}
case TopAbs_EDGE: {

View File

@ -383,6 +383,16 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations
const Standard_Integer theShapeType,
GEOMAlgo_State theState);
/*!
* \brief Explode a shape into edges sorted in a row from a starting point.
* \param theShape - the shape to be exploded on edges.
* \param theStartPoint - the starting point.
* \return Ordered list of edges sorted in a row from a starting point.
*/
Standard_EXPORT Handle(TColStd_HSequenceOfTransient)
GetSubShapeEdgeSorted (const Handle(GEOM_Object) &theShape,
const Handle(GEOM_Object) &theStartPoint);
private:
Handle(GEOM_Object) MakeShape (std::list<Handle(GEOM_Object)> theShapes,
const Standard_Integer theObjectType,
@ -505,6 +515,16 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations
const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
TCollection_AsciiString & theShapeEntries);
/*!
* \brief Explode a shape into edges sorted in a row from a starting point.
* \param theShape - the shape to be exploded on edges.
* \param theStartPoint - the starting point.
* \return Ordered list of edges sorted in a row from a starting point.
*/
Handle(TColStd_HSequenceOfInteger) getSubShapeEdgeSortedIDs
(const Handle(GEOM_Object) &theShape,
const Handle(GEOM_Object) &theStartPoint);
/*!
* \brief Select the object created last
* \param theObj1 - Object 1

View File

@ -1906,3 +1906,44 @@ GEOM::ListOfLong* GEOM_IShapesOperations_i::GetSameIDs
return aSeq._retn();
}
//=============================================================================
/*!
* GetSubShapeEdgeSorted
*/
//=============================================================================
GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSubShapeEdgeSorted
(GEOM::GEOM_Object_ptr theShape,
GEOM::GEOM_Object_ptr theStartPoint)
{
GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
//Set a not done flag
GetOperations()->SetNotDone();
//Get the reference objects
Handle(GEOM_Object) aShape = GetObjectImpl(theShape);
Handle(GEOM_Object) aStartPoint = GetObjectImpl(theStartPoint);
if (aShape.IsNull() || aStartPoint.IsNull()) {
return aSeq._retn();
}
//Get Shapes On Shape
Handle(TColStd_HSequenceOfTransient) aHSeq =
GetOperations()->GetSubShapeEdgeSorted(aShape, aStartPoint);
if (!GetOperations()->IsDone() || aHSeq.IsNull())
return aSeq._retn();
const Standard_Integer aLength = aHSeq->Length();
Standard_Integer i;
aSeq->length(aLength);
for (i = 1; i <= aLength; i++) {
aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i)));
}
return aSeq._retn();
}

View File

@ -271,6 +271,9 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i :
GEOM::ListOfLong* GetSameIDs (GEOM::GEOM_Object_ptr theShapeWhere,
GEOM::GEOM_Object_ptr theShapeWhat);
GEOM::ListOfGO* GetSubShapeEdgeSorted (GEOM::GEOM_Object_ptr theShape,
GEOM::GEOM_Object_ptr theStartPoint);
::GEOMImpl_IShapesOperations* GetOperations()
{ return (::GEOMImpl_IShapesOperations*)GetImpl(); }
};

View File

@ -216,7 +216,6 @@ def TestAll (geompy, math):
Line3 = geompy.MakeLineTwoFaces(prism1_faces[0], prism1_faces[1]) #(2 GEOM_Object)->GEOM_Object
#Create advanced objects
Copy = geompy.MakeCopy(Box) #(GEOM_Object)->GEOM_Object
Prism = geompy.MakePrismVecH(Face, vz, 100.0) #(2 GEOM_Object, Double)->GEOM_Object
Prism2Ways = geompy.MakePrismVecH2Ways(Face, vz, 10.0) #(2 GEOM_Object, Double)->GEOM_Object
PrismTwoPnt = geompy.MakePrism(Face2, p0, pxyz) #(3 GEOM_Object)->GEOM_Object
@ -229,6 +228,7 @@ def TestAll (geompy, math):
tol2d, tol3d, nbiter) #(GEOM_Object, 4 Doubles, Short)->GEOM_Object
Pipe = geompy.MakePipe(Wire, Edge) #(2 GEOM_Object)->GEOM_Object
Sewing = geompy.MakeSewing([Face, S], precision) #(List Of GEOM_Object, Double)->GEOM_Object
Copy = geompy.MakeCopy(Box) #(GEOM_Object)->GEOM_Object
#Transform objects
Translation = geompy.MakeTranslationTwoPoints(Box, px, pz) #(3 GEOM_Object)->GEOM_Object
@ -252,8 +252,8 @@ def TestAll (geompy, math):
Position = geompy.MakePosition(Box, cs1, cs2) #(3 GEOM_Object)->GEOM_Object
Position2 = geompy.PositionAlongPath(Box, Arc, 0.5, 1, 0) #(2 GEOM_Object, 1 Double, 2 Bool)->GEOM_Object
Offset = geompy.MakeOffset(Box, 10.) #(GEOM_Object, Double)->GEOM_Object
Orientation = geompy.ChangeOrientation(Box)
ProjOnWire = geompy.MakeProjectionOnWire(p0, Wire)
Orientation = geompy.ChangeOrientation(Box)
#IDList for Fillet/Chamfer
prism_edges = geompy.ExtractShapes(Prism, geompy.ShapeType["EDGE"], True)
@ -541,4 +541,13 @@ def TestAll (geompy, math):
geompy.RestoreSubShapes(Partition, [Box])
geompy.RestoreSubShapes(Partition1)
# GetSubShapeEdgeSorted
p1 = geompy.GetFirstVertex(Sketcher)
p2 = geompy.GetFirstVertex(Sketcher3d_1)
p3 = geompy.GetFirstVertex(Sketcher3d_2)
geompy.GetSubShapeEdgeSorted(Sketcher, p1, "OrderedEdges")
geompy.GetSubShapeEdgeSorted(Sketcher3d_1, p2, "OrderedEdges")
geompy.GetSubShapeEdgeSorted(Sketcher3d_2, p3, "OrderedEdges")
print "DONE"

View File

@ -6047,6 +6047,38 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
self._autoPublish(ListObj, theName, "subshape")
return ListObj
## Explode a shape into edges sorted in a row from a starting point.
# @param theShape the shape to be exploded on edges.
# @param theStartPoint the starting point.
# @param theName Object name; when specified, this parameter is used
# for result publication in the study. Otherwise, if automatic
# publication is switched on, default value is used for result name.
# @return List of GEOM.GEOM_Object that is actually an ordered list
# of edges sorted in a row from a starting point.
#
# @ref swig_GetSubShapeEdgeSorted "Example"
@ManageTransactions("ShapesOp")
def GetSubShapeEdgeSorted(self, theShape, theStartPoint, theName=None):
"""
Explode a shape into edges sorted in a row from a starting point.
Parameters:
theShape the shape to be exploded on edges.
theStartPoint the starting point.
theName Object name; when specified, this parameter is used
for result publication in the study. Otherwise, if automatic
publication is switched on, default value is used for result name.
Returns:
List of GEOM.GEOM_Object that is actually an ordered list
of edges sorted in a row from a starting point.
"""
# Example: see GEOM_TestAll.py
ListObj = self.ShapesOp.GetSubShapeEdgeSorted(theShape, theStartPoint)
RaiseIfFailed("GetSubShapeEdgeSorted", self.ShapesOp)
self._autoPublish(ListObj, theName, "SortedEdges")
return ListObj
# end of l4_decompose
## @}