示例#1
0
bool FaceMakerCheese::Wire_Compare::operator() (const TopoDS_Wire& w1, const TopoDS_Wire& w2)
{
    Bnd_Box box1, box2;
    if (!w1.IsNull()) {
        BRepBndLib::Add(w1, box1);
        box1.SetGap(0.0);
    }

    if (!w2.IsNull()) {
        BRepBndLib::Add(w2, box2);
        box2.SetGap(0.0);
    }

    return box1.SquareExtent() < box2.SquareExtent();
}
//! return true if w1 bbox is bigger than w2 bbox
//NOTE: this won't necessarily sort the OuterWire correctly (ex smaller wire, same bbox)
/*static*/bool EdgeWalker::wireCompare(const TopoDS_Wire& w1, const TopoDS_Wire& w2)
{
    Bnd_Box box1, box2;
    if (!w1.IsNull()) {
        BRepBndLib::Add(w1, box1);
        box1.SetGap(0.0);
    }

    if (!w2.IsNull()) {
        BRepBndLib::Add(w2, box2);
        box2.SetGap(0.0);
    }

    return box1.SquareExtent() > box2.SquareExtent();
}
void Extrusion::makeDraft(ExtrusionParameters params, const TopoDS_Shape& shape, std::list<TopoDS_Shape>& drafts)
{
    double distanceFwd = tan(params.taperAngleFwd)*params.lengthFwd;
    double distanceRev = tan(params.taperAngleRev)*params.lengthRev;

    gp_Vec vecFwd = gp_Vec(params.dir)*params.lengthFwd;
    gp_Vec vecRev = gp_Vec(params.dir.Reversed())*params.lengthRev;

    bool bFwd = fabs(params.lengthFwd) > Precision::Confusion();
    bool bRev = fabs(params.lengthRev) > Precision::Confusion();
    bool bMid = !bFwd || !bRev || params.lengthFwd*params.lengthRev > 0.0; //include the source shape as loft section?

    TopoDS_Wire sourceWire;
    if (shape.IsNull())
        Standard_Failure::Raise("Not a valid shape");
    if (shape.ShapeType() == TopAbs_WIRE) {
        ShapeFix_Wire aFix;
        aFix.Load(TopoDS::Wire(shape));
        aFix.FixReorder();
        aFix.FixConnected();
        aFix.FixClosed();
        sourceWire = aFix.Wire();
    }
    else if (shape.ShapeType() == TopAbs_FACE) {
        TopoDS_Wire outerWire = ShapeAnalysis::OuterWire(TopoDS::Face(shape));
        sourceWire = outerWire;
    }
    else if (shape.ShapeType() == TopAbs_COMPOUND) {
        TopoDS_Iterator it(shape);
        for (; it.More(); it.Next()) {
            makeDraft(params, it.Value(), drafts);
        }
    }
    else {
        Standard_Failure::Raise("Only a wire or a face is supported");
    }

    if (!sourceWire.IsNull()) {
        std::list<TopoDS_Wire> list_of_sections;

        //first. add wire for reversed part of extrusion
        if (bRev){
            gp_Vec translation = vecRev;
            double offset = distanceRev;

            BRepOffsetAPI_MakeOffset mkOffset;
#if OCC_VERSION_HEX >= 0x060800
            mkOffset.Init(GeomAbs_Arc);
#endif
#if OCC_VERSION_HEX >= 0x070000
            mkOffset.Init(GeomAbs_Intersection);
#endif
            gp_Trsf mat;
            mat.SetTranslation(translation);
            TopLoc_Location loc(mat);
            TopoDS_Wire movedSourceWire = TopoDS::Wire(sourceWire.Moved(loc));

            TopoDS_Shape offsetShape;
            if (fabs(offset)>Precision::Confusion()){
                mkOffset.AddWire(movedSourceWire);
                mkOffset.Perform(offset);

                offsetShape = mkOffset.Shape();
            } else {
                //stupid OCC doesn't understand, what to do when offset value is zero =/
                offsetShape = movedSourceWire;
            }

            if (offsetShape.IsNull())
                Standard_Failure::Raise("Tapered shape is empty");
            TopAbs_ShapeEnum type = offsetShape.ShapeType();
            if (type == TopAbs_WIRE) {
                list_of_sections.push_back(TopoDS::Wire(offsetShape));
            }
            else if (type == TopAbs_EDGE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(offsetShape));
                list_of_sections.push_back(mkWire.Wire());
            }
            else {
                Standard_Failure::Raise("Tapered shape type is not supported");
            }
        }

        //next. Add source wire as middle section. Order is important.
        if (bMid){
            list_of_sections.push_back(sourceWire);
        }

        //finally. Forward extrusion offset wire.
        if (bFwd){
            gp_Vec translation = vecFwd;
            double offset = distanceFwd;

            BRepOffsetAPI_MakeOffset mkOffset;
#if OCC_VERSION_HEX >= 0x060800
            mkOffset.Init(GeomAbs_Arc);
#endif
#if OCC_VERSION_HEX >= 0x070000
            mkOffset.Init(GeomAbs_Intersection);
#endif
            gp_Trsf mat;
            mat.SetTranslation(translation);
            TopLoc_Location loc(mat);
            TopoDS_Wire movedSourceWire = TopoDS::Wire(sourceWire.Moved(loc));

            TopoDS_Shape offsetShape;
            if (fabs(offset)>Precision::Confusion()){
                mkOffset.AddWire(movedSourceWire);
                mkOffset.Perform(offset);

                offsetShape = mkOffset.Shape();
            } else {
                //stupid OCC doesn't understand, what to do when offset value is zero =/
                offsetShape = movedSourceWire;
            }

            if (offsetShape.IsNull())
                Standard_Failure::Raise("Tapered shape is empty");
            TopAbs_ShapeEnum type = offsetShape.ShapeType();
            if (type == TopAbs_WIRE) {
                list_of_sections.push_back(TopoDS::Wire(offsetShape));
            }
            else if (type == TopAbs_EDGE) {
                BRepBuilderAPI_MakeWire mkWire(TopoDS::Edge(offsetShape));
                list_of_sections.push_back(mkWire.Wire());
            }
            else {
                Standard_Failure::Raise("Tapered shape type is not supported");
            }
        }

        //make loft
        BRepOffsetAPI_ThruSections mkGenerator(params.solid ? Standard_True : Standard_False, /*ruled=*/Standard_True);
        for (std::list<TopoDS_Wire>::const_iterator it = list_of_sections.begin(); it != list_of_sections.end(); ++it) {
            const TopoDS_Wire &wire = *it;
            mkGenerator.AddWire(wire);
        }

        try {
#if defined(__GNUC__) && defined (FC_OS_LINUX)
            Base::SignalException se;
#endif
            mkGenerator.Build();
            drafts.push_back(mkGenerator.Shape());
        }
        catch (Standard_Failure &){
            throw;
        }
        catch (...) {
            throw Base::Exception("Unknown exception from BRepOffsetAPI_ThruSections");
        }
    }
}