Пример #1
0
void CrossSection::connectEdges (const std::list<TopoDS_Edge>& edges, std::list<TopoDS_Wire>& wires) const
{
    std::list<TopoDS_Edge> edge_list = edges;
    while (edge_list.size() > 0) {
        BRepBuilderAPI_MakeWire mkWire;
        // add and erase first edge
        mkWire.Add(edge_list.front());
        edge_list.erase(edge_list.begin());

        TopoDS_Wire new_wire = mkWire.Wire();  // current new wire

        // try to connect each edge to the wire, the wire is complete if no more egdes are connectible
        bool found = false;
        do {
            found = false;
            for (std::list<TopoDS_Edge>::iterator pE = edge_list.begin(); pE != edge_list.end();++pE) {
                mkWire.Add(*pE);
                if (mkWire.Error() != BRepBuilderAPI_DisconnectedWire) {
                    // edge added ==> remove it from list
                    found = true;
                    edge_list.erase(pE);
                    new_wire = mkWire.Wire();
                    break;
                }
            }
        }
        while (found);
        wires.push_back(new_wire);
    }
}
Пример #2
0
bool SweepWidget::isPathValid(const Gui::SelectionObject& sel) const
{
    const App::DocumentObject* path = sel.getObject();
    if (!(path && path->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())))
        return false;
    const std::vector<std::string>& sub = sel.getSubNames();


    TopoDS_Shape pathShape;
    const Part::TopoShape& shape = static_cast<const Part::Feature*>(path)->Shape.getValue();
    if (!sub.empty()) {
        try {
            BRepBuilderAPI_MakeWire mkWire;
            for (std::vector<std::string>::const_iterator it = sub.begin(); it != sub.end(); ++it) {
                TopoDS_Shape subshape = shape.getSubShape(it->c_str());
                mkWire.Add(TopoDS::Edge(subshape));
            }
            pathShape = mkWire.Wire();
        }
        catch (...) {
            return false;
        }
    }
    else if (shape._Shape.ShapeType() == TopAbs_EDGE) {
        pathShape = shape._Shape;
    }
    else if (shape._Shape.ShapeType() == TopAbs_WIRE) {
        BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape));
        pathShape = mkWire.Wire();
    }

    return (!pathShape.IsNull());
}
Пример #3
0
//! make a clean wire with sorted, oriented, connected, etc edges
TopoDS_Wire EdgeWalker::makeCleanWire(std::vector<TopoDS_Edge> edges, double tol)
{
    TopoDS_Wire result;
    BRepBuilderAPI_MakeWire mkWire;
    ShapeFix_ShapeTolerance sTol;
    Handle(ShapeExtend_WireData) wireData = new ShapeExtend_WireData();

    for (auto e:edges) {
        wireData->Add(e);
    }

    Handle(ShapeFix_Wire) fixer = new ShapeFix_Wire;
    fixer->Load(wireData);
    fixer->Perform();
    fixer->FixReorder();
    fixer->SetMaxTolerance(tol);
    fixer->ClosedWireMode() = Standard_True;
    fixer->FixConnected(Precision::Confusion());
    fixer->FixClosed(Precision::Confusion());

    for (int i = 1; i <= wireData->NbEdges(); i ++) {
        TopoDS_Edge edge = fixer->WireData()->Edge(i);
        sTol.SetTolerance(edge, tol, TopAbs_VERTEX);
        mkWire.Add(edge);
    }

    result = mkWire.Wire();
    return result;
}
static TopoDS_Wire mkWire1()
{
    BRepBuilderAPI_MakeEdge aMkEdge1 (mkCurve2());
    BRepBuilderAPI_MakeEdge aMkEdge2 (mkCurve3());
    BRepBuilderAPI_MakeWire aMkWire (aMkEdge1, aMkEdge2);
    return aMkWire.Wire();
}
void BRepOffsetAPI_MakeOffsetFix::AddWire(const TopoDS_Wire& Spine)
{
    TopoDS_Wire wire = Spine;
    int numEdges = 0;
    TopExp_Explorer xp(wire, TopAbs_EDGE);
    while (xp.More()) {
        numEdges++;
        xp.Next();
    }
    if (numEdges == 1) {
        TopLoc_Location edgeLocation;

        BRepBuilderAPI_MakeWire mkWire;
        TopExp_Explorer xp(wire, TopAbs_EDGE);
        while (xp.More()) {
            // The trick is to reset the placement of an edge before
            // passing it to BRepOffsetAPI_MakeOffset because then it
            // will create the expected result.
            // Afterwards apply the placement again on the result shape.
            // See the method MakeWire()
            TopoDS_Edge edge = TopoDS::Edge(xp.Current());
            edgeLocation = edge.Location();
            edge.Location(TopLoc_Location());
            mkWire.Add(edge);
            myLocations.push_back(std::make_pair(edge, edgeLocation));
            xp.Next();
        }

        wire = mkWire.Wire();
    }
    mkOffset.AddWire(wire);
    myResult.Nullify();
}
Пример #6
0
bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face) {
	TopoDS_Vertex* vertices = new TopoDS_Vertex[numVerts];
	
	for ( int i = 0; i < numVerts; i ++ ) {
		gp_XY xy (verts[2*i],verts[2*i+1]);
		trsf.Transforms(xy);
		vertices[i] = BRepBuilderAPI_MakeVertex(gp_Pnt(xy.X(),xy.Y(),0.0f));
	}

	BRepBuilderAPI_MakeWire w;
	for ( int i = 0; i < numVerts; i ++ )
		w.Add(BRepBuilderAPI_MakeEdge(vertices[i],vertices[(i+1)%numVerts]));

	IfcGeom::convert_wire_to_face(w.Wire(),face);

	if ( numFillets && *std::max_element(filletRadii, filletRadii + numFillets) > 1e-7 ) {
		BRepFilletAPI_MakeFillet2d fillet (face);
		for ( int i = 0; i < numFillets; i ++ ) {
			const double radius = filletRadii[i];
			if ( radius <= 1e-7 ) continue;
			fillet.AddFillet(vertices[filletIndices[i]],radius);
		}
		fillet.Build();
		if (fillet.IsDone()) {
			face = TopoDS::Face(fillet.Shape());
		} else {
			Logger::Message(Logger::LOG_WARNING, "Failed to process profile fillets");
		}
	}

	delete[] vertices;
	return true;
}
Пример #7
0
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCircleHollowProfileDef* l, TopoDS_Shape& face) {
	const double r = l->Radius() * getValue(GV_LENGTH_UNIT);
	const double t = l->WallThickness() * getValue(GV_LENGTH_UNIT);
	
	if ( r == 0.0f || t == 0.0f ) {
		Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
		return false;
	}
	
	gp_Trsf2d trsf2d;
	bool has_position = true;
#ifdef USE_IFC4
	has_position = l->hasPosition();
#endif
	if (has_position) {
		IfcGeom::Kernel::convert(l->Position(), trsf2d);
	}

	gp_Ax2 ax = gp_Ax2().Transformed(trsf2d);

	BRepBuilderAPI_MakeWire outer;	
	Handle(Geom_Circle) outerCircle = new Geom_Circle(ax, r);
	outer.Add(BRepBuilderAPI_MakeEdge(outerCircle));
	BRepBuilderAPI_MakeFace mf(outer.Wire(), false);

	BRepBuilderAPI_MakeWire inner;	
	Handle(Geom_Circle) innerCirlce = new Geom_Circle(ax, r-t);
	inner.Add(BRepBuilderAPI_MakeEdge(innerCirlce));
	mf.Add(inner);

	ShapeFix_Shape sfs(mf.Face());
	sfs.Perform();
	face = TopoDS::Face(sfs.Shape());	
	return true;		
}
Пример #8
0
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdge* l, TopoDS_Wire& result) {
	if (!l->EdgeStart()->is(IfcSchema::Type::IfcVertexPoint) || !l->EdgeEnd()->is(IfcSchema::Type::IfcVertexPoint)) {
		Logger::Message(Logger::LOG_ERROR, "Only IfcVertexPoints are supported for EdgeStart and -End", l->entity);
		return false;
	}

	IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) l->EdgeStart())->VertexGeometry();
	IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) l->EdgeEnd())->VertexGeometry();
	if (!pnt1->is(IfcSchema::Type::IfcCartesianPoint) || !pnt2->is(IfcSchema::Type::IfcCartesianPoint)) {
		Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", l->entity);
		return false;
	}
	
	gp_Pnt p1, p2;
	if (!convert(((IfcSchema::IfcCartesianPoint*)pnt1), p1) ||
		!convert(((IfcSchema::IfcCartesianPoint*)pnt2), p2))
	{
		return false;
	}

	BRepBuilderAPI_MakeWire mw;
	mw.Add(BRepBuilderAPI_MakeEdge(p1, p2));

	result = mw.Wire();
	return true;
}
void BRepOffsetAPI_MakeOffsetFix::MakeWire(TopoDS_Shape& wire)
{
    // get the edges of the wire and check which of the stored edges
    // serve as input of the wire
    TopTools_MapOfShape aMap;
    TopExp_Explorer xp(wire, TopAbs_EDGE);
    while (xp.More()) {
        aMap.Add(xp.Current());
        xp.Next();
    }

    std::list<TopoDS_Edge> edgeList;
    for (auto itLoc : myLocations) {
        const TopTools_ListOfShape& newShapes = mkOffset.Generated(itLoc.first);
        for (TopTools_ListIteratorOfListOfShape it(newShapes); it.More(); it.Next()) {
            TopoDS_Shape newShape = it.Value();

            if (aMap.Contains(newShape)) {
                newShape.Move(itLoc.second);
                edgeList.push_back(TopoDS::Edge(newShape));
            }
        }
    }

    if (!edgeList.empty()) {
        BRepBuilderAPI_MakeWire mkWire;
        mkWire.Add(edgeList.front());
        edgeList.pop_front();
        wire = mkWire.Wire();

        bool found = false;
        do {
            found = false;
            for (std::list<TopoDS_Edge>::iterator pE = edgeList.begin(); pE != edgeList.end(); ++pE) {
                mkWire.Add(*pE);
                if (mkWire.Error() != BRepBuilderAPI_DisconnectedWire) {
                    // edge added ==> remove it from list
                    found = true;
                    edgeList.erase(pE);
                    wire = mkWire.Wire();
                    break;
                }
            }
        }
        while (found);
    }
}
Пример #10
0
bool SweepWidget::isPathValid(const Gui::SelectionObject& sel) const
{
    const App::DocumentObject* path = sel.getObject();
    if (!(path && path->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())))
        return false;
    const std::vector<std::string>& sub = sel.getSubNames();


    TopoDS_Shape pathShape;
    const Part::TopoShape& shape = static_cast<const Part::Feature*>(path)->Shape.getValue();
    if (!sub.empty()) {
        try {
            BRepBuilderAPI_MakeWire mkWire;
            for (std::vector<std::string>::const_iterator it = sub.begin(); it != sub.end(); ++it) {
                TopoDS_Shape subshape = shape.getSubShape(it->c_str());
                mkWire.Add(TopoDS::Edge(subshape));
            }
            pathShape = mkWire.Wire();
        }
        catch (...) {
            return false;
        }
    }
    else if (shape._Shape.ShapeType() == TopAbs_EDGE) {
        pathShape = shape._Shape;
    }
    else if (shape._Shape.ShapeType() == TopAbs_WIRE) {
        BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape));
        pathShape = mkWire.Wire();
    }
    else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) {
        try {
            TopoDS_Iterator it(shape._Shape);
            for (; it.More(); it.Next()) {
                if ((it.Value().ShapeType() != TopAbs_EDGE) &&
                    (it.Value().ShapeType() != TopAbs_WIRE)) {
                    return false;
                }
            }
            Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape();
            Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape();
            for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next())
                hEdges->Append(xp.Current());

            ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires);
            int len = hWires->Length();
            if (len != 1)
                return false;
            pathShape = hWires->Value(1);
        }
        catch (...) {
            return false;
        }
    }

    return (!pathShape.IsNull());
}
Пример #11
0
static TopoDS_Wire mkWire9()
{
    Standard_Real aCoords[][3] = {
        {0,-1,0},{0,-2,2},{0,0,1},{0,2,2},{0,1,0},{0,2,-2},{0,0,-1},{0,-2,-2}
    };
    Standard_Integer nPoles = sizeof(aCoords)/(sizeof(Standard_Real)*3);
    Handle(Geom_Curve) aCurve = mkPBSplineCurve (nPoles, aCoords);
    BRepBuilderAPI_MakeEdge aMkEdge (aCurve);
    BRepBuilderAPI_MakeWire aMkWire (aMkEdge);
    return aMkWire.Wire();
}
Пример #12
0
TopoDS_Shape OCCPartFactory::makeCube( const Standard_Real width,
                                       const Standard_Real height,
                                       const Standard_Real depth)
{
    // define points
    gp_Pnt pt1( -width / 2.0, 0.0, 0.0 );
    gp_Pnt pt2( -width / 2.0, -depth / 2.0, 0.0 );
    gp_Pnt pt3( width / 2.0, -depth / 2.0, 0.0 );
    gp_Pnt pt4( width /2.0, 0.0, 0.0 );

    // define segments
    Handle_Geom_TrimmedCurve seg1 = GC_MakeSegment( pt1, pt2 );
    Handle_Geom_TrimmedCurve seg2 = GC_MakeSegment( pt2, pt3 );
    Handle_Geom_TrimmedCurve seg3 = GC_MakeSegment( pt3, pt4 );

    // make edge
    TopoDS_Edge edge1 = BRepBuilderAPI_MakeEdge( seg1 );
    TopoDS_Edge edge2 = BRepBuilderAPI_MakeEdge( seg2 );
    TopoDS_Edge edge3 = BRepBuilderAPI_MakeEdge( seg3 );

    // make wire
    TopoDS_Wire wire1 = BRepBuilderAPI_MakeWire( edge1, edge2, edge3 );

    //Complete Profile
    gp_Ax1 xAxis = gp::OX();
    gp_Trsf transfer;
    
    transfer.SetMirror( xAxis );
    
    BRepBuilderAPI_Transform aBRepTrsf( wire1 , transfer );
    TopoDS_Shape mirroredShape = aBRepTrsf.Shape();
    TopoDS_Wire mirroredWire1 = TopoDS::Wire( mirroredShape );
    
    BRepBuilderAPI_MakeWire mkWire;
    
    mkWire.Add( wire1 );
    mkWire.Add( mirroredWire1 );
    
    TopoDS_Wire wireProfile = mkWire.Wire();
    
    //Body : Prism the Profile
    TopoDS_Face faceProfile = BRepBuilderAPI_MakeFace( wireProfile );
    gp_Vec prismVec( 0.0 , 0.0 , height );
    
    TopoDS_Shape cube = BRepPrimAPI_MakePrism( faceProfile, prismVec);

//     cube.setMaterial( Graphic3d_NOM_JADE );

//     Handle_AIS_Shape shape = new AIS_Shape( cube );
//     shape->SetColor( Quantity_NOC_RED );

//     return shape;
    return cube;
}
Пример #13
0
TopoDS_Wire CCPACSWingProfile::GetWire()
{
    Update();
    // rebuild closed wire
    BRepBuilderAPI_MakeWire closedWireBuilder;
    closedWireBuilder.Add(profileAlgo->GetUpperLowerWire());
    if (!profileAlgo->GetTrailingEdge().IsNull()) {
        closedWireBuilder.Add(profileAlgo->GetTrailingEdge());
    }
        
    return closedWireBuilder.Wire();
}
Пример #14
0
void Pipe::buildPipePath(const Part::TopoShape& shape, const std::vector< std::string >& subedge, TopoDS_Shape& path) {

    if (!shape._Shape.IsNull()) {
        try {
            if (!subedge.empty()) {
                //if(SpineTangent.getValue())
                    //getContiniusEdges(shape, subedge);
                
                BRepBuilderAPI_MakeWire mkWire;
                for (std::vector<std::string>::const_iterator it = subedge.begin(); it != subedge.end(); ++it) {
                    TopoDS_Shape subshape = shape.getSubShape(it->c_str());
                    mkWire.Add(TopoDS::Edge(subshape));
                }
                path = mkWire.Wire();
            }
            else if (shape._Shape.ShapeType() == TopAbs_EDGE) {
                path = shape._Shape;
            }
            else if (shape._Shape.ShapeType() == TopAbs_WIRE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape));
                path = mkWire.Wire();
            }
            else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) {
                TopoDS_Iterator it(shape._Shape);
                for (; it.More(); it.Next()) {
                    if (it.Value().IsNull())
                        throw Base::Exception("In valid element in spine.");
                    if ((it.Value().ShapeType() != TopAbs_EDGE) &&
                        (it.Value().ShapeType() != TopAbs_WIRE)) {
                        throw Base::Exception("Element in spine is neither an edge nor a wire.");
                    }
                }

                Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape();
                Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape();
                for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next())
                    hEdges->Append(xp.Current());

                ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires);
                int len = hWires->Length();
                if (len != 1)
                    throw Base::Exception("Spine is not connected.");
                path = hWires->Value(1);
            }
            else {
                throw Base::Exception("Spine is neither an edge nor a wire.");
            }
        }
        catch (Standard_Failure) {
            throw Base::Exception("Invalid spine.");
        }
    }
}
Пример #15
0
static TopoDS_Wire mkWire3()
{
    BRepBuilderAPI_MakeEdge aMkEdge1 (mkCurve1());
    Standard_Real aCoords[][3] = {
        {0,10,20},{0,20,10},{0,20,0},{0,0,0}
    };
    Standard_Integer nPoles = sizeof(aCoords)/(sizeof(Standard_Real)*3);
    Handle(Geom_Curve) aCurve = mkBezierCurve (nPoles, aCoords);
    BRepBuilderAPI_MakeEdge aMkEdge2 (aCurve);
    BRepBuilderAPI_MakeWire aMkWire (aMkEdge1, aMkEdge2);
    return aMkWire.Wire();
}
Пример #16
0
// Make a TopoDS_Wire from a list of TopoDS_Edges
TopoDS_Wire edgesToWire(std::vector<TopoDS_Edge> Edges) {
    TopoDS_Wire occwire;
    std::vector<TopoDS_Edge>::iterator iEdge;
    BRepBuilderAPI_MakeWire mkWire;
    for (iEdge = Edges.begin(); iEdge != Edges.end(); ++iEdge){
        mkWire.Add(*iEdge);
        if (!mkWire.IsDone()) {
            Base::Console().Message("FT2FC Trace edgesToWire failed to add wire\n");
        }
    }
    occwire = mkWire.Wire();
    BRepLib::BuildCurves3d(occwire);
    return(occwire);
}
Пример #17
0
bool IfcGeom::convert(const Ifc2x3::IfcPolyline::ptr l, TopoDS_Wire& result) {
	Ifc2x3::IfcCartesianPoint::list points = l->Points();

	BRepBuilderAPI_MakeWire w;
	gp_Pnt P1;gp_Pnt P2;
	for( Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) {
		IfcGeom::convert(*it,P2);
		if ( it != points->begin() && ( !P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) )
			w.Add(BRepBuilderAPI_MakeEdge(P1,P2));
		P1 = P2;
	}

	result = w.Wire();
	return true;
}
Пример #18
0
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCenterLineProfileDef* l, TopoDS_Shape& face) {
	const double d = l->Thickness() * getValue(GV_LENGTH_UNIT) / 2.;

	TopoDS_Wire wire;
	if (!convert_wire(l->Curve(), wire)) return false;

	// BRepOffsetAPI_MakeOffset insists on creating circular arc
	// segments for joining the curves that constitute the center
	// line. This is probably not in accordance with the IFC spec.
	// Although it does not specify a method to join segments
	// explicitly, it does dictate 'a constant thickness along the
	// curve'. Therefore for simple singular wires a quick
	// alternative is provided that uses a straight join.

	TopExp_Explorer exp(wire, TopAbs_EDGE);
	TopoDS_Edge edge = TopoDS::Edge(exp.Current());
	exp.Next();

	if (!exp.More()) {
		double u1, u2;
		Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, u1, u2);

		Handle(Geom_TrimmedCurve) trim = new Geom_TrimmedCurve(curve, u1, u2);

		Handle(Geom_OffsetCurve) c1 = new Geom_OffsetCurve(trim,  d, gp::DZ());
		Handle(Geom_OffsetCurve) c2 = new Geom_OffsetCurve(trim, -d, gp::DZ());

		gp_Pnt c1a, c1b, c2a, c2b;
		c1->D0(c1->FirstParameter(), c1a);
		c1->D0(c1->LastParameter(), c1b);
		c2->D0(c2->FirstParameter(), c2a);
		c2->D0(c2->LastParameter(), c2b);

		BRepBuilderAPI_MakeWire mw;
		mw.Add(BRepBuilderAPI_MakeEdge(c1));
		mw.Add(BRepBuilderAPI_MakeEdge(c1a, c2a));
		mw.Add(BRepBuilderAPI_MakeEdge(c2));
		mw.Add(BRepBuilderAPI_MakeEdge(c2b, c1b));
		
		face = BRepBuilderAPI_MakeFace(mw.Wire());
	} else {
		BRepOffsetAPI_MakeOffset offset(BRepBuilderAPI_MakeFace(gp_Pln(gp::Origin(), gp::DZ())));
		offset.AddWire(wire);
		offset.Perform(d);
		face = BRepBuilderAPI_MakeFace(TopoDS::Wire(offset));
	}
	return true;
}
Пример #19
0
int OCCWire::createWire(std::vector<OCCEdge *> edges)
{
    try {
        BRepBuilderAPI_MakeWire MW;
        for (unsigned i=0; i<edges.size(); i++) {
            OCCEdge *edge = edges[i];
            MW.Add(edge->getEdge());
        }
        
        BRepBuilderAPI_WireError error = MW.Error();
        switch (error)
        {
            case BRepBuilderAPI_EmptyWire:
            {
                StdFail_NotDone::Raise("Wire empty");
                break;
            }
            case BRepBuilderAPI_DisconnectedWire:
            {
                StdFail_NotDone::Raise("Disconnected wire");
                break;
            }
            case BRepBuilderAPI_NonManifoldWire :
            {
                StdFail_NotDone::Raise("non-manifold wire");
                break;
            }
        }
        
        this->setShape(MW.Wire());
        
        // possible fix shape
        if (!this->fixShape())
            StdFail_NotDone::Raise("Shapes not valid");
        
    } catch(Standard_Failure &err) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        const Standard_CString msg = e->GetMessageString();
        if (msg != NULL && strlen(msg) > 1) {
            setErrorMessage(msg);
        } else {
            setErrorMessage("Failed to create wire");
        }
        return 0;
    }
    return 1;
}
Пример #20
0
bool IfcGeom::Kernel::convert(const IfcSchema::IfcSubedge* l, TopoDS_Wire& result) {
	TopoDS_Wire temp;
	if (convert_wire(l->ParentEdge(), result) && convert((IfcSchema::IfcEdge*) l, temp)) {
		TopExp_Explorer exp(result, TopAbs_EDGE);
		TopoDS_Edge edge = TopoDS::Edge(exp.Current());
		Standard_Real u1, u2;
		Handle(Geom_Curve) crv = BRep_Tool::Curve(edge, u1, u2);
		TopoDS_Vertex v1, v2;
		TopExp::Vertices(temp, v1, v2);
		BRepBuilderAPI_MakeWire mw;
		mw.Add(BRepBuilderAPI_MakeEdge(crv, v1, v2));
		result = mw.Wire();
		return true;
	} else {
		return false;
	}
}
Пример #21
0
// Returns the wing profile lower and upper wire fused
TopoDS_Wire CCPACSWingProfile::GetSplitWire()
{
    Update();
    // rebuild closed wire
    BRepBuilderAPI_MakeWire closedWireBuilder;
    closedWireBuilder.Add(profileAlgo->GetLowerWire());
    closedWireBuilder.Add(profileAlgo->GetUpperWire());
    if (!profileAlgo->GetTrailingEdge().IsNull()) {
        closedWireBuilder.Add(profileAlgo->GetTrailingEdge());
    }
    closedWireBuilder.Build();
    
    if (!closedWireBuilder.IsDone()) {
        throw CTiglError("Error creating closed wing profile");
    }
        
    return closedWireBuilder.Wire();
}
App::DocumentObjectExecReturn *Torus::execute(void)
{
    if (Radius1.getValue() < Precision::Confusion())
        return new App::DocumentObjectExecReturn("Radius of torus too small");
    if (Radius2.getValue() < Precision::Confusion())
        return new App::DocumentObjectExecReturn("Radius of torus too small");
    try {
#if 1
        // Build a torus
        gp_Circ circle;
        circle.SetRadius(Radius2.getValue());
        gp_Pnt pos(Radius1.getValue(),0,0);
        gp_Dir dir(0,1,0);
        circle.SetAxis(gp_Ax1(pos, dir));

        BRepBuilderAPI_MakeEdge mkEdge(circle, Base::toRadians<double>(Angle1.getValue()+180.0f),
                                               Base::toRadians<double>(Angle2.getValue()+180.0f));
        BRepBuilderAPI_MakeWire mkWire;
        mkWire.Add(mkEdge.Edge());
        BRepBuilderAPI_MakeFace mkFace(mkWire.Wire());
        BRepPrimAPI_MakeRevol mkRevol(mkFace.Face(), gp_Ax1(gp_Pnt(0,0,0), gp_Dir(0,0,1)),
            Base::toRadians<double>(Angle3.getValue()), Standard_True);
        TopoDS_Shape ResultShape = mkRevol.Shape();
#else
        BRepPrimAPI_MakeTorus mkTorus(Radius1.getValue(),
                                      Radius2.getValue(),
                                      Angle1.getValue()/180.0f*Standard_PI,
                                      Angle2.getValue()/180.0f*Standard_PI,
                                      Angle3.getValue()/180.0f*Standard_PI);
        const TopoDS_Solid& ResultShape = mkTorus.Solid();
#endif
        this->Shape.setValue(ResultShape);
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        return new App::DocumentObjectExecReturn(e->GetMessageString());
    }

    return App::DocumentObject::StdReturn;
}
Пример #23
0
TopoDS_Shape
MakeBottle(const Standard_Real myWidth, const Standard_Real myHeight,
           const Standard_Real myThickness)
{

    BRepBuilderAPI_MakeWire wireMaker;

    // Profile : Define Support Points
    {
        Handle(TColgp_HArray1OfPnt) gp_array = new TColgp_HArray1OfPnt(1, 4);
        gp_Pnt p0(-myWidth / 2., 0, 0);
        gp_Pnt p4(myWidth / 2., 0, 0);

//    gp_array->SetValue(0, p0);
        gp_array->SetValue(1, gp_Pnt(-myWidth / 2., -myThickness / 4., 0));
        gp_array->SetValue(2, gp_Pnt(0, -myThickness / 2., 0));
        gp_array->SetValue(3, gp_Pnt(myWidth / 2., -myThickness / 4., 0));
        gp_array->SetValue(4, p4);

        GeomAPI_Interpolate sp(gp_array, true, 1.0e-3);
        sp.Perform();

        wireMaker.Add(BRepBuilderAPI_MakeEdge(sp.Curve()));
    }
    // Body : Prism the Profile
    TopoDS_Face myFaceProfile = BRepBuilderAPI_MakeFace(wireMaker.Wire());
    gp_Vec aPrismVec(0, 0, myHeight);
    TopoDS_Shape myBody = BRepPrimAPI_MakePrism(myFaceProfile, aPrismVec);



    // Building the Resulting Compound
    TopoDS_Compound aRes;
    BRep_Builder aBuilder;
    aBuilder.MakeCompound(aRes);
    aBuilder.Add(aRes, myBody);
//    aBuilder.Add(aRes, myThreading);

    return aRes;
}
Пример #24
0
bool IfcGeom::convert(const Ifc2x3::IfcPolyLoop::ptr l, TopoDS_Wire& result) {
	Ifc2x3::IfcCartesianPoint::list points = l->Polygon();

	BRepBuilderAPI_MakeWire w;
	gp_Pnt P1;gp_Pnt P2;gp_Pnt F;
	int count = 0;
	for( Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) {
		IfcGeom::convert(*it,P2);
		if ( it != points->begin() && ( !P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) ) {
			w.Add(BRepBuilderAPI_MakeEdge(P1,P2));
			count ++;
		} else if ( ! count ) F = P2;		
		P1 = P2;
	}
	if ( !P1.IsEqual(F,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) {
		w.Add(BRepBuilderAPI_MakeEdge(P1,F));
		count ++;
	}
	if ( count < 3 ) return false;

	result = w.Wire();
	return true;
}
Пример #25
0
App::DocumentObjectExecReturn *Sweep::execute(void)
{
    if (Sections.getSize() == 0)
        return new App::DocumentObjectExecReturn("No sections linked.");
    App::DocumentObject* spine = Spine.getValue();
    if (!(spine && spine->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())))
        return new App::DocumentObjectExecReturn("No spine linked.");
    const std::vector<std::string>& subedge = Spine.getSubValues();

    TopoDS_Shape path;
    const Part::TopoShape& shape = static_cast<Part::Feature*>(spine)->Shape.getValue();
    if (!shape._Shape.IsNull()) {
        try {
            if (!subedge.empty()) {
                BRepBuilderAPI_MakeWire mkWire;
                for (std::vector<std::string>::const_iterator it = subedge.begin(); it != subedge.end(); ++it) {
                    TopoDS_Shape subshape = shape.getSubShape(it->c_str());
                    mkWire.Add(TopoDS::Edge(subshape));
                }
                path = mkWire.Wire();
            }
            else if (shape._Shape.ShapeType() == TopAbs_EDGE) {
                path = shape._Shape;
            }
            else if (shape._Shape.ShapeType() == TopAbs_WIRE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape._Shape));
                path = mkWire.Wire();
            }
            else if (shape._Shape.ShapeType() == TopAbs_COMPOUND) {
                TopoDS_Iterator it(shape._Shape);
                for (; it.More(); it.Next()) {
                    if (it.Value().IsNull())
                        return new App::DocumentObjectExecReturn("In valid element in spine.");
                    if ((it.Value().ShapeType() != TopAbs_EDGE) &&
                        (it.Value().ShapeType() != TopAbs_WIRE)) {
                        return new App::DocumentObjectExecReturn("Element in spine is neither an edge nor a wire.");
                    }
                }

                Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape();
                Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape();
                for (TopExp_Explorer xp(shape._Shape, TopAbs_EDGE); xp.More(); xp.Next())
                    hEdges->Append(xp.Current());

                ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_True, hWires);
                int len = hWires->Length();
                if (len != 1)
                    return new App::DocumentObjectExecReturn("Spine is not connected.");
                path = hWires->Value(1);
            }
            else {
                return new App::DocumentObjectExecReturn("Spine is neither an edge nor a wire.");
            }
        }
        catch (Standard_Failure) {
            return new App::DocumentObjectExecReturn("Invalid spine.");
        }
    }

    try {
        TopTools_ListOfShape profiles;
        const std::vector<App::DocumentObject*>& shapes = Sections.getValues();
        std::vector<App::DocumentObject*>::const_iterator it;
        for (it = shapes.begin(); it != shapes.end(); ++it) {
            if (!(*it)->isDerivedFrom(Part::Feature::getClassTypeId()))
                return new App::DocumentObjectExecReturn("Linked object is not a shape.");
            TopoDS_Shape shape = static_cast<Part::Feature*>(*it)->Shape.getValue();
            if (shape.IsNull())
                return new App::DocumentObjectExecReturn("Linked shape is invalid.");

            // Extract first element of a compound
            if (shape.ShapeType() == TopAbs_COMPOUND) {
                TopoDS_Iterator it(shape);
                for (; it.More(); it.Next()) {
                    if (!it.Value().IsNull()) {
                        shape = it.Value();
                        break;
                    }
                }
            }
            // There is a weird behaviour of BRepOffsetAPI_MakePipeShell when trying to add the wire as is.
            // If we re-create the wire then everything works fine.
            // http://forum.freecadweb.org/viewtopic.php?f=10&t=2673&sid=fbcd2ff4589f0b2f79ed899b0b990648#p20268
            if (shape.ShapeType() == TopAbs_FACE) {
                TopoDS_Wire faceouterWire = ShapeAnalysis::OuterWire(TopoDS::Face(shape));
                profiles.Append(faceouterWire);
            }
            else if (shape.ShapeType() == TopAbs_WIRE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Wire(shape));
                profiles.Append(mkWire.Wire());
            }
            else if (shape.ShapeType() == TopAbs_EDGE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(shape));
                profiles.Append(mkWire.Wire());
            }
            else if (shape.ShapeType() == TopAbs_VERTEX) {
                profiles.Append(shape);
            }
            else {
                return new App::DocumentObjectExecReturn("Linked shape is not a vertex, edge, wire nor face.");
            }
        }

        Standard_Boolean isSolid = Solid.getValue() ? Standard_True : Standard_False;
        Standard_Boolean isFrenet = Frenet.getValue() ? Standard_True : Standard_False;
        BRepBuilderAPI_TransitionMode transMode;
        switch (Transition.getValue()) {
            case 1: transMode = BRepBuilderAPI_RightCorner;
                break;
            case 2: transMode = BRepBuilderAPI_RoundCorner;
                break;
            default: transMode = BRepBuilderAPI_Transformed;
                break;
        }

        if (path.ShapeType() == TopAbs_EDGE) {
            BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(path));
            path = mkWire.Wire();
        }

        BRepOffsetAPI_MakePipeShell mkPipeShell(TopoDS::Wire(path));
        mkPipeShell.SetMode(isFrenet);
        mkPipeShell.SetTransitionMode(transMode);
        TopTools_ListIteratorOfListOfShape iter;
        for (iter.Initialize(profiles); iter.More(); iter.Next()) {
            mkPipeShell.Add(TopoDS_Shape(iter.Value()));
        }

        if (!mkPipeShell.IsReady())
            Standard_Failure::Raise("shape is not ready to build");
        mkPipeShell.Build();
        if (isSolid)
            mkPipeShell.MakeSolid();

        this->Shape.setValue(mkPipeShell.Shape());
        return App::DocumentObject::StdReturn;
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        return new App::DocumentObjectExecReturn(e->GetMessageString());
    }
    catch (...) {
        return new App::DocumentObjectExecReturn("A fatal error occurred when making the sweep");
    }
}
Пример #26
0
// constructor method
int TopoShapeWirePy::PyInit(PyObject* args, PyObject* /*kwd*/)
{
    PyObject *pcObj;
    if (PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pcObj)) {
        BRepBuilderAPI_MakeWire mkWire;
        const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(pcObj)->getTopoShapePtr()->_Shape;
        if (sh.IsNull()) {
            PyErr_SetString(PyExc_TypeError, "given shape is invalid");
            return -1;
        }
        if (sh.ShapeType() == TopAbs_EDGE)
            mkWire.Add(TopoDS::Edge(sh));
        else if (sh.ShapeType() == TopAbs_WIRE)
            mkWire.Add(TopoDS::Wire(sh));
        else {
            PyErr_SetString(PyExc_TypeError, "shape is neither edge nor wire");
            return -1;
        }

        try {
            getTopoShapePtr()->_Shape = mkWire.Wire();
            return 0;
        }
        catch (Standard_Failure) {
            Handle_Standard_Failure e = Standard_Failure::Caught();
            PyErr_SetString(PyExc_Exception, e->GetMessageString());
            return -1;
        }
    }

    PyErr_Clear();
    if (PyArg_ParseTuple(args, "O!", &(PyList_Type), &pcObj)) {
        BRepBuilderAPI_MakeWire mkWire;
        Py::List list(pcObj);
        for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
            PyObject* item = (*it).ptr();
            if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
                const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->_Shape;
                if (sh.IsNull()) {
                    PyErr_SetString(PyExc_TypeError, "given shape is invalid");
                    return -1;
                }
                if (sh.ShapeType() == TopAbs_EDGE)
                    mkWire.Add(TopoDS::Edge(sh));
                else if (sh.ShapeType() == TopAbs_WIRE)
                    mkWire.Add(TopoDS::Wire(sh));
                else {
                    PyErr_SetString(PyExc_TypeError, "shape is neither edge nor wire");
                    return -1;
                }
            }
            else {
                PyErr_SetString(PyExc_TypeError, "item is not a shape");
                return -1;
            }
        }

        try {
            getTopoShapePtr()->_Shape = mkWire.Wire();
            return 0;
        }
        catch (Standard_Failure) {
            Handle_Standard_Failure e = Standard_Failure::Caught();
            PyErr_SetString(PyExc_Exception, e->GetMessageString());
            return -1;
        }
    }

    PyErr_SetString(PyExc_Exception, "edge or wire or list of edges and wires expected");
    return -1;
}
Пример #27
0
//=======================================================================
// profile
// command to build a profile
//=======================================================================
Sketcher_Profile::Sketcher_Profile(const char* aCmd)
{
  enum {line, circle, point, none} move;

  Standard_Integer i = 1;
  Standard_Real x0, y0, x, y, dx, dy;
  x0 = y0 = x = y = dy = 0;
  dx = 1;

  Standard_Boolean first, stayfirst, face, close;
  first = Standard_True;
  stayfirst = face = close = Standard_False;

  Standard_Integer reversed = 0;
  Standard_Integer control_Tolerance = 0;

  TopoDS_Shape S;
  TopoDS_Vertex MP;
  BRepBuilderAPI_MakeWire MW;
  gp_Ax3 DummyHP(gp::XOY());
  gp_Pln P(DummyHP);
  TopLoc_Location TheLocation;
  Handle(Geom_Surface) Surface;

  myOK = Standard_False;
  myError = 0;

  //TCollection_AsciiString aCommand(CORBA::string_dup(aCmd));
  TCollection_AsciiString aCommand ((char*)aCmd);
  TCollection_AsciiString aToken = aCommand.Token(":", 1);
  int n = 0;
  // porting to WNT
  TColStd_Array1OfAsciiString aTab (0, aCommand.Length() - 1);
  if ( aCommand.Length() )
  {
    while(aToken.Length() != 0) {
      if(aCommand.Token(":", n + 1).Length() > 0)
        aTab(n) = aCommand.Token(":", n + 1);
      aToken = aCommand.Token(":", ++n);
    }
    n = n - 1;
  }
  if ( aTab.Length() && aTab(0).Length() )
    while(i < n) {
      Standard_Real length = 0, radius = 0, angle = 0;
      move = point;

      int n1 = 0;
      TColStd_Array1OfAsciiString a (0, aTab(0).Length());
      aToken = aTab(i).Token(" ", 1);
      while (aToken.Length() != 0) {
        if (aTab(i).Token(" ", n1 + 1).Length() > 0)
          a(n1) = aTab(i).Token(" ", n1 + 1);
        aToken = aTab(i).Token(" ", ++n1);
      }
      n1 = n1 - 1;

      switch(a(0).Value(1))
      {
      case 'F':
        {
          if (n1 != 3) goto badargs;
          if (!first) {
            MESSAGE("profile : The F instruction must precede all moves");
            return;
          }
          x0 = x = a(1).RealValue();
          y0 = y = a(2).RealValue();
          stayfirst = Standard_True;
          break;
        }
      case 'O':
        {
          if (n1 != 4) goto badargs;
          P.SetLocation(gp_Pnt(a(1).RealValue(), a(2).RealValue(), a(3).RealValue()));
          stayfirst = Standard_True;
          break;
        }
      case 'P':
        {
          if (n1 != 7) goto badargs;
          gp_Vec vn(a(1).RealValue(), a(2).RealValue(), a(3).RealValue());
          gp_Vec vx(a(4).RealValue(), a(5).RealValue(), a(6).RealValue());
          if (vn.Magnitude() <= Precision::Confusion() || vx.Magnitude() <= Precision::Confusion()) {
            MESSAGE("profile : null direction");
            return;
          }
          gp_Ax2 ax(P.Location(), vn, vx);
          P.SetPosition(ax);
          stayfirst = Standard_True;
          break;
        }
      case 'X':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (a(0) == "XX")
            length -= x;
          dx = 1; dy = 0;
          move = line;
          break;
        }
      case 'Y':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (a(0) == "YY")
            length -= y;
          dx = 0; dy = 1;
          move = line;
          break;
        }
      case 'L':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (Abs(length) > Precision::Confusion())
            move = line;
          else
            move = none;
          break;
        }
      case 'T':
        {
          if (n1 != 3) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          if (a(0) == "TT") {
            vx -= x;
            vy -= y;
          }
          length = Sqrt(vx * vx + vy * vy);
          if (length > Precision::Confusion()) {
            move = line;
            dx = vx / length;
            dy = vy / length;
          }
          else
            move = none;
          break;
        }
      case 'R':
        {
          if (n1 != 2) goto badargs;
          angle = a(1).RealValue() * PI180;
          if (a(0) == "RR") {
            dx = Cos(angle);
            dy = Sin(angle);
          }
          else {
            Standard_Real c = Cos(angle);
            Standard_Real s = Sin(angle);
            Standard_Real t = c * dx - s * dy;
            dy = s * dx + c * dy;
            dx = t;
          }
          break;
        }
      case 'D':
        {
          if (n1 != 3) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          length = Sqrt(vx * vx + vy * vy);
          if (length > Precision::Confusion()) {
            dx = vx / length;
            dy = vy / length;
          }
          else
            move = none;
          break;
        }
      case 'C':
        {
          if (n1 != 3) goto badargs;
          radius = a(1).RealValue();
          if (Abs(radius) > Precision::Confusion()) {
            angle = a(2).RealValue() * PI180;
            move = circle;
          }
          else
            move = none;
          break;
        }
      case 'A':                                // TAngential arc by end point   
        { 
          if (n1 != 3) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue(); 
          if (a(0) == "AA") {
            vx -= x;
            vy -= y;
          }
          Standard_Real det = dx * vy - dy * vx;
          if ( Abs(det) > Precision::Confusion()) {
            Standard_Real c = (dx * vx + dy * vy)                                            
                              / Sqrt((dx * dx + dy * dy) * (vx * vx + vy * vy));                 // Cosine of alpha = arc of angle / 2 , alpha in [0,Pi]
            radius = (vx * vx + vy * vy)* Sqrt(dx * dx + dy * dy)                                // radius = distance between start and end point / 2 * sin(alpha)  
                     / (2.0 * det);	                                                             // radius is > 0 or < 0
            if (Abs(radius) > Precision::Confusion()) {
              angle = 2.0 * acos(c); 	                                                         // angle in [0,2Pi]  
              move = circle;
            }
            else
              move = none;
            break;
          } 
          else
            move = none;
          break;
        } 
      case 'U':                                // Arc by end point and radiUs
        { 
          if (n1 != 5) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          radius  = a(3).RealValue();
          reversed = a(4).IntegerValue();
          if (a(0) == "UU") {                 // Absolute
            vx -= x;
            vy -= y;
          }
          Standard_Real length = Sqrt(vx * vx + vy * vy);
          if ( (4.0 - (vx * vx + vy * vy) / (radius * radius) >= 0.0 ) && (length > Precision::Confusion()) ) {
            Standard_Real c = 0.5 * Sqrt(4.0 - (vx * vx + vy * vy) / (radius * radius));        // Cosine of alpha = arc angle / 2 , alpha in [0,Pi/2]
            angle = 2.0 * acos(c); 	                                                            // angle in [0,Pi]
            if ( reversed == 2 )
              angle = angle - 2 * PI; 
            dx =    0.5 * (  vy * 1.0/radius 
                           + vx * Sqrt(4.0  / (vx * vx + vy * vy) - 1.0 / (radius * radius)));    
            dy = -  0.5 * (  vx * 1.0/radius 
                           - vy * Sqrt(4.0  / (vx * vx + vy * vy) - 1.0 / (radius * radius)));    
            move = circle;
          }
          else{
            move = none;
          }
          break;
        }	 
      case 'E':                                // Arc by end point and cEnter
        { 
          if (n1 != 7) goto badargs;
          Standard_Real vx = a(1).RealValue();
          Standard_Real vy = a(2).RealValue();
          Standard_Real vxc  = a(3).RealValue();
          Standard_Real vyc  = a(4).RealValue();
          reversed = a(5).IntegerValue();
          control_Tolerance = a(6).IntegerValue();

          if (a(0) == "EE") {                 // Absolute
            vx -= x;
            vy -= y;
            vxc -= x;
            vyc -= y; 
          }
          radius = Sqrt( vxc * vxc + vyc * vyc );
          Standard_Real det = vx * vyc - vy * vxc;
          Standard_Real length = Sqrt(vx * vx + vy * vy);
          Standard_Real length2 = Sqrt((vx-vxc) * (vx-vxc) + (vy-vyc) * (vy-vyc));
          Standard_Real length3 = Sqrt(vxc * vxc + vyc * vyc);
          Standard_Real error = Abs(length2 - radius);
          myError = error;
          if ( error > Precision::Confusion() ){
            MESSAGE("Warning : The specified end point is not on the Arc, distance = "<<error);
          }
          if ( error > Precision::Confusion() && control_Tolerance == 1)                      // Don't create the arc if the end point 
            move = none;                                                                      // is too far from it
          else if ( (length > Precision::Confusion()) && 
                    (length2 > Precision::Confusion()) && 
                    (length3 > Precision::Confusion()) ) {
            Standard_Real c = ( radius * radius - (vx * vxc + vy * vyc) ) 
                            / ( radius * Sqrt((vx-vxc) * (vx-vxc) + (vy-vyc) * (vy-vyc)) ) ;  // Cosine of arc angle 
            angle = acos(c);                                                                  // angle in [0,Pi] 
            if ( reversed == 2 )
              angle = angle - 2 * PI;
            if (det < 0)
              angle = -angle; 
            dx =  vyc / radius;
            dy = -vxc / radius; 
            move = circle;
          }
          else {
            move = none;
          }
          break;
        }	
      case 'I':
        {
          if (n1 != 2) goto badargs;
          length = a(1).RealValue();
          if (a(0) == "IX") {
            if (Abs(dx) < Precision::Confusion()) {
              MESSAGE("profile : cannot intersect, arg "<<i-1);
              return;
            }
            length = (length - x) / dx;
          }
          else if (a(0) == "IY") {
            if (Abs(dy) < Precision::Confusion()) {
              MESSAGE("profile : cannot intersect, arg "<<i-1);
              return;
            }
            length = (length - y) / dy;
          }
          if (Abs(length) > Precision::Confusion())
            move = line;
          else
            move = none;
          break;
        }
      case 'W':
        {
          if (a(0) == "WW")
            close = Standard_True;
          else if(a(0) == "WF") {
            close = Standard_True;
            face = Standard_True;
          }
          i = n - 1;
          break;
        }
      default:
        {
          MESSAGE("profile : unknown code " << a(i));
          return;
        }
    }

again :
    switch (move)
    {
    case line :
      {
        if (length < 0) {
          length = -length;
          dx = -dx;
          dy = -dy;
        }
        Handle(Geom2d_Line) l = new Geom2d_Line(gp_Pnt2d(x,y),gp_Dir2d(dx,dy));
        BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(l,P),0,length);
        if (!ME.IsDone())
          return;
        MW.Add(ME);
        x += length*dx;
        y += length*dy;
        break;
      }
    case circle :
      {
        Standard_Boolean sense = Standard_True;
        if (radius < 0) {
          radius = -radius;
          sense = !sense;
          dx = -dx;
          dy = -dy;
        }
        gp_Ax2d ax(gp_Pnt2d(x-radius*dy,y+radius*dx),gp_Dir2d(dy,-dx));
        if (angle < 0) {
          angle = -angle;
          sense = !sense;
        }
        Handle(Geom2d_Circle) c = new Geom2d_Circle(ax,radius,sense);
        BRepBuilderAPI_MakeEdge ME (GeomAPI::To3d(c,P),0,angle);
        if (!ME.IsDone())
          return;
        MW.Add(ME);
        gp_Pnt2d p;
        gp_Vec2d v;
        c->D1(angle,p,v);
        x = p.X();
        y = p.Y();
        dx = v.X() / radius;
        dy = v.Y() / radius;
        break;
      }
    case point:
      {
        MP = BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, 0.0));
        break;
      }
    case none:
      {
        i = n - 1;
        break;
      }
    }

    // update first
    first = stayfirst;
    stayfirst = Standard_False;

    if(!(dx == 0 && dy == 0))
      myLastDir.SetCoord(dx, dy, 0.0);
    else
      return;
    myLastPoint.SetX(x);
    myLastPoint.SetY(y);

    // next segment....
    i++;
    if ((i == n) && close) {
      // the closing segment
      dx = x0 - x;
      dy = y0 - y;
      length = Sqrt(dx * dx + dy * dy);
      move = line;
      if (length > Precision::Confusion()) {
        dx = dx / length;
        dy = dy / length;
        goto again;
      }
    }
  }

  // get the result, face or wire
  if (move == none) {
    return;
  } else if (move == point) {
    S = MP;
  } else if (face) {
    if (!MW.IsDone()) {
      return;
    }
    BRepBuilderAPI_MakeFace MF (P, MW.Wire());
    if (!MF.IsDone()) {
      return;
    }
    S = MF;
  } else {
    if (!MW.IsDone()) {
      return;
    }
    S = MW;
  }

  if(!TheLocation.IsIdentity())
    S.Move(TheLocation);

  myShape = S;
  myOK = true;
  return;

  badargs :
    MESSAGE("profile : bad number of arguments");
    return;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IFillet1d aCI (aFunction);

  Handle(GEOM_Function) aRefShape = aCI.GetShape();
  TopoDS_Shape aShape = aRefShape->GetValue();
  if (aShape.IsNull())
    return 0;
  if (aShape.ShapeType() != TopAbs_WIRE)
    Standard_ConstructionError::Raise("Wrong arguments: polyline as wire must be given");

  TopoDS_Wire aWire = TopoDS::Wire(aShape);

  double rad = aCI.GetR();

  if ( rad < Precision::Confusion())
    return 0;

  // collect vertices for make fillet
  TopTools_ListOfShape aVertexList;
  TopTools_MapOfShape mapShape;
  int aLen = aCI.GetLength();
  if ( aLen > 0 ) {
    for (int ind = 1; ind <= aLen; ind++) {
      TopoDS_Shape aShapeVertex;
      if (GEOMImpl_ILocalOperations::GetSubShape
          (aWire, aCI.GetVertex(ind), aShapeVertex))
        if (mapShape.Add(aShapeVertex))
          aVertexList.Append( aShapeVertex );
    }
  } else { // get all vertices from wire
    TopExp_Explorer anExp( aWire, TopAbs_VERTEX );
    for ( ; anExp.More(); anExp.Next() ) {
      if (mapShape.Add(anExp.Current()))
        aVertexList.Append( anExp.Current() );
    }
  }
  if (aVertexList.IsEmpty())
    Standard_ConstructionError::Raise("Invalid input no vertices to make fillet");

  //INFO: this algorithm implemented in assumption that user can select both
  //  vertices of some edges to make fillet. In this case we should remember
  //  already modified initial edges to take care in next fillet step
  TopTools_DataMapOfShapeShape anEdgeToEdgeMap;

  //iterates on vertices, and make fillet on each couple of edges
  //collect result fillet edges in list
  TopTools_ListOfShape aListOfNewEdge;
  // remember relation between initial and modified map
  TopTools_IndexedDataMapOfShapeListOfShape aMapVToEdges;
  TopExp::MapShapesAndAncestors( aWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges );
  TopTools_ListIteratorOfListOfShape anIt( aVertexList );
  for ( ; anIt.More(); anIt.Next() ) {
    TopoDS_Vertex aV = TopoDS::Vertex( anIt.Value() );
    if ( aV.IsNull() || !aMapVToEdges.Contains( aV ) )
      continue;
    const TopTools_ListOfShape& aVertexEdges = aMapVToEdges.FindFromKey( aV );
    if ( aVertexEdges.Extent() != 2 )
      continue; // no input data to make fillet
    TopoDS_Edge anEdge1 = TopoDS::Edge( aVertexEdges.First() );
    TopoDS_Edge anEdge2 = TopoDS::Edge( aVertexEdges.Last() );
    // check if initial edges already modified in previous fillet operation
    if ( anEdgeToEdgeMap.IsBound( anEdge1 ) ) anEdge1 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge1 ));
    if ( anEdgeToEdgeMap.IsBound( anEdge2 ) ) anEdge2 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge2 ));
    if ( anEdge1.IsNull() || anEdge2.IsNull() || anEdge1.IsSame( anEdge2 ) )
      continue; //no input data to make fillet

    // create plane on 2 edges
    gp_Pln aPlane;
    if ( !takePlane(anEdge1, anEdge2, aV, aPlane) )
      continue; // seems edges does not belong to same plane or parallel (fillet can not be build)

    GEOMImpl_Fillet1d aFilletAlgo(anEdge1, anEdge2, aPlane);
    if ( !aFilletAlgo.Perform(rad) )
      continue; // can not create fillet with given radius

    // take fillet result in given vertex
    TopoDS_Edge aModifE1, aModifE2;
    TopoDS_Edge aNewE = aFilletAlgo.Result(BRep_Tool::Pnt(aV), aModifE1, aModifE2);
    if (aNewE.IsNull())
      continue; // no result found

    // add  new created edges and take modified edges
    aListOfNewEdge.Append( aNewE );

    // check if face edges modified,
    // if yes, than map to original edges (from vertex-edges list), because edges can be modified before
    if (aModifE1.IsNull() || !anEdge1.IsSame( aModifE1 ))
      addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.First()), aModifE1 );
    if (aModifE2.IsNull() || !anEdge2.IsSame( aModifE2 ))
      addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.Last()), aModifE2 );
  }

  if ( anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() ) {
    StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius");
    return 0;
  }

  // create new wire instead of original
  for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() ) {
    TopoDS_Shape anEdge = anExp.Current();
    if ( !anEdgeToEdgeMap.IsBound( anEdge ) )
      aListOfNewEdge.Append( anEdge );
    else if (!anEdgeToEdgeMap.Find( anEdge ).IsNull())
      aListOfNewEdge.Append( anEdgeToEdgeMap.Find( anEdge ) );
  }

  GEOMImpl_IShapesOperations::SortShapes( aListOfNewEdge );

  BRepBuilderAPI_MakeWire aWireTool;
  aWireTool.Add( aListOfNewEdge );
  aWireTool.Build();
  if (!aWireTool.IsDone())
    return 0;

  aWire = aWireTool.Wire();
  aFunction->SetValue(aWire);
  log.SetTouched(Label());

  return 1;
}
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire& wire) {
	if ( getValue(GV_PLANEANGLE_UNIT)<0 ) {
		Logger::Message(Logger::LOG_WARNING,"Creating a composite curve without unit information:",l->entity);

		// Temporarily pretend we do have unit information
		setValue(GV_PLANEANGLE_UNIT,1.0);
		
		bool succes_radians = false;
        bool succes_degrees = false;
        bool use_radians = false;
        bool use_degrees = false;

		// First try radians
		TopoDS_Wire wire_radians, wire_degrees;
        try {
		    succes_radians = IfcGeom::Kernel::convert(l,wire_radians);
        } catch (...) {}

		// Now try degrees
		setValue(GV_PLANEANGLE_UNIT,0.0174532925199433);
        try {
		    succes_degrees = IfcGeom::Kernel::convert(l,wire_degrees);
        } catch (...) {}

		// Restore to unknown unit state
		setValue(GV_PLANEANGLE_UNIT,-1.0);

		if ( succes_degrees && ! succes_radians ) {
			use_degrees = true;
		} else if ( succes_radians && ! succes_degrees ) {
			use_radians = true;
		} else if ( succes_radians && succes_degrees ) {
			if ( wire_degrees.Closed() && ! wire_radians.Closed() ) {
				use_degrees = true;
			} else if ( wire_radians.Closed() && ! wire_degrees.Closed() ) {
				use_radians = true;
			} else {
				// No heuristic left to prefer the one over the other,
				// apparently both variants are equally succesful.
				// The curve might be composed of only straight segments.
				// Let's go with the wire created using radians as that
				// at least is a SI unit.
				use_radians = true;
			}
		}

		if ( use_radians ) {
			Logger::Message(Logger::LOG_NOTICE,"Used radians to create composite curve");
            wire = wire_radians;
		} else if ( use_degrees ) {
			Logger::Message(Logger::LOG_NOTICE,"Used degrees to create composite curve");
            wire = wire_degrees;
		}

		return use_radians || use_degrees;
	}
	IfcSchema::IfcCompositeCurveSegment::list::ptr segments = l->Segments();
	BRepBuilderAPI_MakeWire w;
	//TopoDS_Vertex last_vertex;
	for( IfcSchema::IfcCompositeCurveSegment::list::it it = segments->begin(); it != segments->end(); ++ it ) {
		IfcSchema::IfcCurve* curve = (*it)->ParentCurve();
		TopoDS_Wire wire2;
		if ( !convert_wire(curve,wire2) ) {
			Logger::Message(Logger::LOG_ERROR,"Failed to convert curve:",curve->entity);
			continue;
		}
		if ( ! (*it)->SameSense() ) wire2.Reverse();
		ShapeFix_ShapeTolerance FTol;
		FTol.SetTolerance(wire2, getValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_WIRE);
		/*if ( it != segments->begin() ) {
			TopExp_Explorer exp (wire2,TopAbs_VERTEX);
			const TopoDS_Vertex& first_vertex = TopoDS::Vertex(exp.Current());
			gp_Pnt first = BRep_Tool::Pnt(first_vertex);
			gp_Pnt last = BRep_Tool::Pnt(last_vertex);
			Standard_Real distance = first.Distance(last);
			if ( distance > ALMOST_ZERO ) {
				w.Add( BRepBuilderAPI_MakeEdge( last_vertex, first_vertex ) );
			}
		}*/
		w.Add(wire2);
		//last_vertex = w.Vertex();
		if ( w.Error() != BRepBuilderAPI_WireDone ) {
			Logger::Message(Logger::LOG_ERROR,"Failed to join curve segments:",l->entity);
			return false;
		}
	}
	wire = w.Wire();
	return true;
}
bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire& wire) {
	IfcSchema::IfcCurve* basis_curve = l->BasisCurve();
	bool isConic = basis_curve->is(IfcSchema::Type::IfcConic);
	double parameterFactor = isConic ? getValue(GV_PLANEANGLE_UNIT) : getValue(GV_LENGTH_UNIT);
	Handle(Geom_Curve) curve;
	if ( !convert_curve(basis_curve,curve) ) return false;
	bool trim_cartesian = l->MasterRepresentation() == IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN;
	IfcEntityList::ptr trims1 = l->Trim1();
	IfcEntityList::ptr trims2 = l->Trim2();
	bool trimmed1 = false;
	bool trimmed2 = false;
	unsigned sense_agreement = l->SenseAgreement() ? 0 : 1;
	double flts[2];
	gp_Pnt pnts[2];
	bool has_flts[2] = {false,false};
	bool has_pnts[2] = {false,false};
	BRepBuilderAPI_MakeWire w;
	for ( IfcEntityList::it it = trims1->begin(); it != trims1->end(); it ++ ) {
		IfcUtil::IfcBaseClass* i = *it;
		if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
			IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[sense_agreement] );
			has_pnts[sense_agreement] = true;
		} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
			const double value = *((IfcSchema::IfcParameterValue*)i);
			flts[sense_agreement] = value * parameterFactor;
			has_flts[sense_agreement] = true;
		}
	}
	for ( IfcEntityList::it it = trims2->begin(); it != trims2->end(); it ++ ) {
		IfcUtil::IfcBaseClass* i = *it;
		if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
			IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[1-sense_agreement] );
			has_pnts[1-sense_agreement] = true;
		} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
			const double value = *((IfcSchema::IfcParameterValue*)i);
			flts[1-sense_agreement] = value * parameterFactor;
			has_flts[1-sense_agreement] = true;
		}
	}
	trim_cartesian &= has_pnts[0] && has_pnts[1];
	bool trim_cartesian_failed = !trim_cartesian;
	if ( trim_cartesian ) {
		if ( pnts[0].Distance(pnts[1]) < getValue(GV_WIRE_CREATION_TOLERANCE) ) {
			Logger::Message(Logger::LOG_WARNING,"Skipping segment with length below tolerance level:",l->entity);
			return false;
		}
		ShapeFix_ShapeTolerance FTol;
		TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex(pnts[0]);
		TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex(pnts[1]);
		FTol.SetTolerance(v1, getValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX);
		FTol.SetTolerance(v2, getValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX);
		BRepBuilderAPI_MakeEdge e (curve,v1,v2);
		if ( ! e.IsDone() ) {
			BRepBuilderAPI_EdgeError err = e.Error();
			if ( err == BRepBuilderAPI_PointProjectionFailed ) {
				Logger::Message(Logger::LOG_WARNING,"Point projection failed for:",l->entity);
				trim_cartesian_failed = true;
			}
		} else {
			w.Add(e.Edge());
		}
	}
	if ( (!trim_cartesian || trim_cartesian_failed) && (has_flts[0] && has_flts[1]) ) {
		// The Geom_Line is constructed from a gp_Pnt and gp_Dir, whereas the IfcLine
		// is defined by an IfcCartesianPoint and an IfcVector with Magnitude. Because
		// the vector is normalised when passed to Geom_Line constructor the magnitude
		// needs to be factored in with the IfcParameterValue here.
		if ( basis_curve->is(IfcSchema::Type::IfcLine) ) {
			IfcSchema::IfcLine* line = static_cast<IfcSchema::IfcLine*>(basis_curve);
			const double magnitude = line->Dir()->Magnitude();
			flts[0] *= magnitude; flts[1] *= magnitude;
		}
		if ( basis_curve->is(IfcSchema::Type::IfcEllipse) ) {
			IfcSchema::IfcEllipse* ellipse = static_cast<IfcSchema::IfcEllipse*>(basis_curve);
			double x = ellipse->SemiAxis1() * getValue(GV_LENGTH_UNIT);
			double y = ellipse->SemiAxis2() * getValue(GV_LENGTH_UNIT);
			const bool rotated = y > x;
			if (rotated) {
				flts[0] -= M_PI / 2.;
				flts[1] -= M_PI / 2.;
			}
		}
		if ( isConic && ALMOST_THE_SAME(fmod(flts[1]-flts[0],(double)(M_PI*2.0)),0.0f) ) {
			w.Add(BRepBuilderAPI_MakeEdge(curve));
		} else {
			BRepBuilderAPI_MakeEdge e (curve,flts[0],flts[1]);
			w.Add(e.Edge());
		}			
	} else if ( trim_cartesian_failed && (has_pnts[0] && has_pnts[1]) ) {
		w.Add(BRepBuilderAPI_MakeEdge(pnts[0],pnts[1]));
	}
	if ( w.IsDone() ) {
		wire = w.Wire();
		return true;
	} else {
		return false;
	}
}