#include <GeomAlgoAPI_Copy.h>
#include <GeomAlgoAPI_MapShapesAndAncestors.h>
#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
#include <GeomAPI_Edge.h>
#include <GeomAPI_Pln.h>
#include <GeomAPI_Pnt.h>
#include <GeomAPI_Wire.h>
#include <GeomAPI_WireExplorer.h>
+#include <GeomAPI_ShapeIterator.h>
#include <GEOMImpl_Fillet1d.hxx>
build(theBaseWire, theFilletVertices, theFilletRadius);
}
-void GeomAlgoAPI_Fillet1D::build(const GeomShapePtr& theBaseWire,
+void GeomAlgoAPI_Fillet1D::build(const GeomShapePtr& theBaseShape,
const ListOfShape& theFilletVertices,
const double theRadius)
{
- if (!theBaseWire || theFilletVertices.empty() || theRadius < 0.)
+ if (!theBaseShape.get() || theFilletVertices.empty() || theRadius < 0.)
return;
myFailedVertices.clear();
+ GeomShapePtr aShape;
+
+ if (theBaseShape->isWire())
+ aShape = buildWire(theBaseShape, theFilletVertices, theRadius);
+ else if (theBaseShape->isCompound()) {
+ std::list<GeomShapePtr> aShapes;
+ for (GeomAPI_ShapeIterator it (theBaseShape); it.more(); it.next()) {
+ GeomShapePtr aSubShape = it.current();
+ if (aSubShape->isWire()) {
+ // get only fillet vertices of current wire
+ ListOfShape aFilletVertices;
+ std::set<GeomShapePtr, GeomAPI_Shape::Comparator> aFilletVerticesSet
+ (theFilletVertices.begin(), theFilletVertices.end());
+ for (GeomAPI_WireExplorer anExp(aSubShape->wire()); anExp.more(); anExp.next()) {
+ if (aFilletVerticesSet.find(anExp.currentVertex()) != aFilletVerticesSet.end())
+ aFilletVertices.push_back(anExp.currentVertex());
+ }
+
+ GeomShapePtr aShape_i = buildWire(aSubShape, aFilletVertices, theRadius);
+ if (aShape_i.get() != NULL)
+ aShapes.push_back(aShape_i);
+ else
+ aShapes.push_back(aSubShape);
+ }
+ else {
+ setDone(false);
+ myError = "Input shape for fillet is neither a wire nor a compound of wires";
+ return;
+ }
+ }
+ aShape = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
+ myModified[theBaseShape].push_back(aShape);
+ } else {
+ setDone(false);
+ myError = "Input shape for fillet is neither a wire nor a compound";
+ return;
+ }
+
+ setShape(aShape);
+ setDone(myFailedVertices.empty());
+}
+
+GeomShapePtr GeomAlgoAPI_Fillet1D::buildWire(const GeomShapePtr& theBaseWire,
+ const ListOfShape& theFilletVertices,
+ const double theRadius)
+{
+ std::shared_ptr<GeomAPI_Shape> aShape;
+ if (!theBaseWire.get() || theFilletVertices.empty() || theRadius < 0.)
+ return aShape;
+
// store all edges of a base wire as modified, because they will be rebuild by ShapeFix
for (GeomAPI_WireExplorer aWExp(theBaseWire->wire()); aWExp.more(); aWExp.next()) {
GeomShapePtr aCurrent = aWExp.current();
GeomPlanePtr aPlane = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
if (!aPlane)
- return; // non-planar edges
+ return aShape; // non-planar edges
TopoDS_Edge anEdge1 = TopoDS::Edge(anEdges.front()->impl<TopoDS_Shape>());
TopoDS_Edge anEdge2 = TopoDS::Edge(anEdges.back()->impl<TopoDS_Shape>());
aNewEdges.push_back(aWExp.current());
for (ListOfShape::iterator anIt = aNewEdges.begin(); anIt != aNewEdges.end(); ++anIt)
aBuilder.Add(aNewWire, TopoDS::Edge((*anIt)->impl<TopoDS_Shape>()));
- }
- for (MapModified::iterator aGenIt = myGenerated.begin(); aGenIt != myGenerated.end(); ++aGenIt) {
- for (ListOfShape::iterator anIt = aGenIt->second.begin(); anIt != aGenIt->second.end(); ++anIt)
+
+ ListOfShape aNewEdges1;
+ generated(aWExp.currentVertex(), aNewEdges1);
+ for (ListOfShape::iterator anIt = aNewEdges1.begin(); anIt != aNewEdges1.end(); ++anIt)
aBuilder.Add(aNewWire, TopoDS::Edge((*anIt)->impl<TopoDS_Shape>()));
}
// fix the wire connectivity
aNewWire = aFixWire.WireAPIMake();
if (aNewWire.IsNull()) {
myFailedVertices = theFilletVertices;
- return;
+ return aShape;
}
// update the map of modified shapes, because the edges are changed by ShapeFix
aNewWire = aReorderedWire;
}
- std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
- aShape->setImpl(new TopoDS_Shape(aNewWire));
- myModified[theBaseWire].push_back(aShape);
-
- setShape(aShape);
- setDone(myFailedVertices.empty());
+ std::shared_ptr<GeomAPI_Shape> aResShape(new GeomAPI_Shape);
+ aResShape->setImpl(new TopoDS_Shape(aNewWire));
+ myModified[theBaseWire].push_back(aResShape);
+ return aResShape;
}
void GeomAlgoAPI_Fillet1D::generated(const GeomShapePtr theOldShape,
public:
/// Run fillet operation on a set of vertices with fixed radius.
- /// \param theBaseWire a changing Wire
- /// \param theFilletVertices list of edges the fillet is performed on
+ /// \param theBaseWire a wire or a compound of wires
+ /// \param theFilletVertices list of vertices the fillet is performed on
/// \param theFilletRadius radius of the fillet
GEOMALGOAPI_EXPORT GeomAlgoAPI_Fillet1D(const GeomShapePtr& theBaseWire,
const ListOfShape& theFilletVertices,
const ListOfShape& failedVertices() const { return myFailedVertices; }
private:
- /// Perform 1d-fillet on wire
- /// \param theBaseWire a changing wire
- /// \param theFilletVertices list of vertices of filler
+ /// Perform 1d-fillet on a wire or a compound of wires
+ /// \param theBaseShape the base wire or a compound of wires for fillet
+ /// \param theFilletVertices list of vertices of fillet
/// \param theRadius fillet radius
- void build(const GeomShapePtr& theBaseWire,
+ void build(const GeomShapePtr& theBaseShape,
const ListOfShape& theFilletVertices,
const double theRadius);
+ /// Perform 1d-fillet on wire
+ /// \param theBaseWire the base wire for fillet
+ /// \param theFilletVertices list of vertices of fillet
+ /// \param theRadius fillet radius
+ GeomShapePtr buildWire(const GeomShapePtr& theBaseWire,
+ const ListOfShape& theFilletVertices,
+ const double theRadius);
+
private:
MapModified myGenerated;
MapModified myModified;
} else { // reset the old array
if (theSize) {
if (theSize != myArray->Length()) { // old data is not kept, a new array is created
- Handle(TColStd_HArray1OfInteger) aNewArray = new TColStd_HArray1OfInteger(0, theSize - 1);
+ Handle(TColStd_HArray1OfInteger) aNewArray =
+ new TColStd_HArray1OfInteger(0, theSize - 1, 0);
myArray->ChangeArray(aNewArray);
if (sendUpdated)
owner()->data()->sendAttributeUpdated(this);
// find vertices for fillet
std::set<GeomShapePtr, GeomAPI_Shape::Comparator> aFilletVertices;
- // ??? TODO: if aResWire is a compound of wires - process each wire ???
- if (aResWire->isWire()) {
- for (MapShapeToShapes::const_iterator anIt = aSubshapes.begin();
- anIt != aSubshapes.end(); ++anIt) {
- // vertex should have 2 adjacent edges
- if (anIt->second.size() != 2)
- continue;
+ for (MapShapeToShapes::const_iterator anIt = aSubshapes.begin();
+ anIt != aSubshapes.end(); ++anIt) {
+ // vertex should have 2 adjacent edges
+ if (anIt->second.size() != 2)
+ continue;
- // both edges should be linear
- ListOfShape anEdges;
- anEdges.insert(anEdges.end(), anIt->second.begin(), anIt->second.end());
- GeomEdgePtr anEdge1 (new GeomAPI_Edge(anEdges.front()));
- GeomEdgePtr anEdge2 (new GeomAPI_Edge(anEdges.back()));
- if (!anEdge1->isLine() || !anEdge2->isLine())
- continue;
+ // both edges should be linear
+ ListOfShape anEdges;
+ anEdges.insert(anEdges.end(), anIt->second.begin(), anIt->second.end());
+ GeomEdgePtr anEdge1 (new GeomAPI_Edge(anEdges.front()));
+ GeomEdgePtr anEdge2 (new GeomAPI_Edge(anEdges.back()));
+ if (!anEdge1->isLine() || !anEdge2->isLine())
+ continue;
- // skip vertices, which smoothly connect adjacent edges
- GeomVertexPtr aSharedVertex(new GeomAPI_Vertex(anIt->first));
- if (GeomAlgoAPI_ShapeTools::isTangent(anEdge1, anEdge2, aSharedVertex))
- continue;
+ // skip vertices, which smoothly connect adjacent edges
+ GeomVertexPtr aSharedVertex(new GeomAPI_Vertex(anIt->first));
+ if (GeomAlgoAPI_ShapeTools::isTangent(anEdge1, anEdge2, aSharedVertex))
+ continue;
- aFilletVertices.insert(anIt->first);
- }
+ aFilletVertices.insert(anIt->first);
}
if (!aFilletVertices.empty()) {
isOK = false; // the wire needs correction
- ListOfShape aVerticesList;
- for (GeomAPI_WireExplorer anExp (aResWire->wire()); anExp.more(); anExp.next()) {
- GeomShapePtr aVertex = anExp.currentVertex();
- if (aFilletVertices.find(aVertex) != aFilletVertices.end())
- aVerticesList.push_back(aVertex);
- }
+ ListOfShape aVerticesList (aFilletVertices.begin(), aFilletVertices.end());
// Fillet1D on all linear edges intersections
std::shared_ptr<GeomAlgoAPI_Fillet1D> aFilletBuilder
}
else {
ListOfShape aFailedVertices = aFilletBuilder->failedVertices();
- if (aFailedVertices.size() != 0 &&
- aFailedVertices.size() != aVerticesList.size()) {
+ if (aFailedVertices.size() != 0) {
// Exclude failed vertices and also vertices, joined
// with failed by one edge, and run algorithm once again
ListOfShape::iterator itVertices = aFailedVertices.begin();
}
else {
// Fillet1D one more try
- ListOfShape aVerticesList1;
- for (GeomAPI_WireExplorer anExp (aResWire->wire()); anExp.more(); anExp.next()) {
- GeomShapePtr aVertex = anExp.currentVertex();
- if (aFilletVertices.find(aVertex) != aFilletVertices.end())
- aVerticesList1.push_back(aVertex);
- }
+ ListOfShape aVerticesList1 (aFilletVertices.begin(), aFilletVertices.end());
std::shared_ptr<GeomAlgoAPI_Fillet1D> aFilletBuilder1
(new GeomAlgoAPI_Fillet1D(aResWire, aVerticesList1, theValue));