예제 #1
0
App::DocumentObjectExecReturn *DrawViewDetail::execute(void)
{
    if (!keepUpdated()) {
        return App::DocumentObject::StdReturn;
    }

    App::DocumentObject* baseObj = BaseView.getValue();
    if (!baseObj)  {
        Base::Console().Log("INFO - DVD::execute - No BaseView - creation?\n");
        return DrawView::execute();
    }

    DrawViewPart* dvp = nullptr;
    if (!baseObj->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
        return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object");
    } else {
        dvp = static_cast<DrawViewPart*>(baseObj);
    }

    TopoDS_Shape shape = dvp->getSourceShapeFused();
    if (shape.IsNull()) {
        return new App::DocumentObjectExecReturn("DVD - Linked shape object is invalid");
    }

    Base::Vector3d anchor = AnchorPoint.getValue();    //this is a 2D point (in unrotated coords)
    Base::Vector3d dirDetail = dvp->Direction.getValue();

    double shapeRotate = dvp->Rotation.getValue();                      //degrees CW?
    if (dvp->isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) {
        DrawProjGroupItem* dpgi= static_cast<TechDraw::DrawProjGroupItem*>(dvp);
        shapeRotate += dpgi->getRotateAngle() * 180.0/M_PI;            // to degrees from radians
    }
 
    double radius = getFudgeRadius();
    double scale = getScale();

    BRepBuilderAPI_Copy BuilderCopy(shape);
    TopoDS_Shape myShape = BuilderCopy.Shape();

    //rotate the copied shape to match orientation of BaseView and center it on origin
    gp_Pnt gpCenter = TechDrawGeometry::findCentroid(myShape,           //centre of unrotated shape
                                                     dirDetail);
    Base::Vector3d shapeCenter = Base::Vector3d(gpCenter.X(),gpCenter.Y(),gpCenter.Z());
    gp_Ax2 viewAxis = getViewAxis(shapeCenter, dirDetail, false);
    myShape = TechDrawGeometry::rotateShape(myShape,                    //rotate to match Base shape
                                            viewAxis,
                                            -shapeRotate);
    myShape = TechDrawGeometry::moveShape(myShape,                     //centre on origin
                                          -shapeCenter);
//    shapeCenter = Base::Vector3d(0.0,0.0,0.0);
    gpCenter = TechDrawGeometry::findCentroid(myShape,
                                              dirDetail);
    shapeCenter = Base::Vector3d(gpCenter.X(),gpCenter.Y(),gpCenter.Z());
   
    Bnd_Box bbxSource;
    bbxSource.SetGap(0.0);
    BRepBndLib::Add(myShape, bbxSource);
    double diag = sqrt(bbxSource.SquareExtent());

    Base::Vector3d extentFar,extentNear;
    extentFar = shapeCenter + dirDetail * diag;
    extentNear = shapeCenter + dirDetail * diag * -1.0;

    anchor = Base::Vector3d(anchor.x,anchor.y, 0.0);
    viewAxis = getViewAxis(shapeCenter, dirDetail, false);                //change view axis to (0,0,0)
    Base::Vector3d offsetCenter3D = DrawUtil::toR3(viewAxis, anchor);     //displacement in R3
    Base::Vector3d stdZ(0.0,0.0,1.0);
    if (DrawUtil::checkParallel(dirDetail,stdZ)) {
        extentNear = extentNear + offsetCenter3D;
    } else {
        extentNear = extentNear - offsetCenter3D;
    }

    gp_Dir cylDir(dirDetail.x,dirDetail.y,dirDetail.z);
    gp_Pnt cylPoint(extentNear.x,extentNear.y,extentNear.z);
    gp_Ax2 cylAxis(cylPoint,cylDir);

    BRepPrimAPI_MakeCylinder mkCyl(cylAxis, radius, (extentFar-extentNear).Length());
    TopoDS_Shell sh = mkCyl.Cylinder().Shell();
    BRepBuilderAPI_MakeSolid mkSol(sh);
    TopoDS_Solid tool = mkSol.Solid();

    BRepAlgoAPI_Common mkCommon(myShape,tool);
    if (!mkCommon.IsDone()) {
        Base::Console().Log("DVD::execute - mkCommon not done\n");
        return new App::DocumentObjectExecReturn("DVD::execute - mkCommon not done");
    }
    if (mkCommon.Shape().IsNull()) {
        Base::Console().Log("DVD::execute - mkCommon.Shape is Null\n");
        return new App::DocumentObjectExecReturn("DVD::execute - mkCommon.Shape is Null");
    }

    //Did we get a solid?
    TopExp_Explorer xp;
    xp.Init(mkCommon.Shape(),TopAbs_SOLID);
    if (!(xp.More() == Standard_True)) {
        Base::Console().Message("DVD::execute - mkCommon.Shape is not a solid!\n");
    }
    TopoDS_Shape detail = mkCommon.Shape();
    Bnd_Box testBox;
    testBox.SetGap(0.0);
    BRepBndLib::Add(detail, testBox);
    if (testBox.IsVoid()) {
        Base::Console().Message("DrawViewDetail - detail area contains no geometry\n");
        return new App::DocumentObjectExecReturn("DVDetail - detail area contains no geometry");
    }

//for debugging show compound instead of common
//    BRep_Builder builder;
//    TopoDS_Compound Comp;
//    builder.MakeCompound(Comp);
//    builder.Add(Comp, tool);
//    builder.Add(Comp, myShape);

    gp_Pnt inputCenter;
    try {
        inputCenter = TechDrawGeometry::findCentroid(tool,
                                                     Direction.getValue());
        TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(detail,
                                                    inputCenter,
                                                    scale);
        viewAxis = getViewAxis(Base::Vector3d(inputCenter.X(),inputCenter.Y(),inputCenter.Z()),Direction.getValue());
        if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) {
            mirroredShape = TechDrawGeometry::rotateShape(mirroredShape,
                                                          viewAxis,
                                                          Rotation.getValue());         //degrees cw?
        }
        geometryObject = buildGeometryObject(mirroredShape,viewAxis);
        geometryObject->pruneVertexGeom(Base::Vector3d(0.0,0.0,0.0),Radius.getValue() * scale);      //remove vertices beyond clipradius

#if MOD_TECHDRAW_HANDLE_FACES
    if (handleFaces()) {
        try {
            extractFaces();
        }
        catch (Standard_Failure& e4) {
            Base::Console().Log("LOG - DVD::execute - extractFaces failed for %s - %s **\n",getNameInDocument(),e4.GetMessageString());
            return new App::DocumentObjectExecReturn(e4.GetMessageString());
        }
    }

#endif //#if MOD_TECHDRAW_HANDLE_FACES
    }
    catch (Standard_Failure& e1) {
        Base::Console().Log("LOG - DVD::execute - base shape failed for %s - %s **\n",getNameInDocument(),e1.GetMessageString());
        return new App::DocumentObjectExecReturn(e1.GetMessageString());
    }

    requestPaint();
    dvp->requestPaint();

    return App::DocumentObject::StdReturn;
}
예제 #2
0
std::vector<TopoDS_Wire> EdgeWalker::sortStrip(std::vector<TopoDS_Wire> fw, bool includeBiggest)
{
    std::vector<TopoDS_Wire> sortedWires = sortWiresBySize(fw,false);           //biggest 1st
    if (!sortedWires.size()) {
        Base::Console().Log("INFO - DVP::extractFaces - no sorted Wires!\n");
        return sortedWires;                                     // might happen in the middle of changes?
    }

    //find the largest wire (OuterWire of graph) using bbox
    Bnd_Box bigBox;
    if (sortedWires.size() && !sortedWires.front().IsNull()) {
        BRepBndLib::Add(sortedWires.front(), bigBox);
        bigBox.SetGap(0.0);
    }
    std::vector<std::size_t> toBeChecked;
    std::vector<TopoDS_Wire>::iterator it = sortedWires.begin() + 1;
    for (; it != sortedWires.end(); it++) {
        if (!(*it).IsNull()) {
            Bnd_Box littleBox;
            BRepBndLib::Add((*it), littleBox);
            littleBox.SetGap(0.0);
            if (bigBox.SquareExtent() > littleBox.SquareExtent()) {
                break;
            } else {
                auto position = std::distance( sortedWires.begin(), it );    //get an index from iterator
                toBeChecked.push_back(position);
            }
        }
    }

    //unfortuneately, faces can have same bbox, but not be same size.  need to weed out biggest
    if (toBeChecked.size() == 0) {
        //nobody had as big a bbox as first element of sortedWires
        if (!includeBiggest) {
            sortedWires.erase(sortedWires.begin());
        }
    } else if (toBeChecked.size() > 0) {
        BRepBuilderAPI_MakeFace mkFace(sortedWires.front());
        const TopoDS_Face& face = mkFace.Face();
        GProp_GProps props;
        BRepGProp::SurfaceProperties(face, props);
        double bigArea = props.Mass();
        unsigned int bigIndex = 0;
        for (unsigned int idx = 0; idx < toBeChecked.size(); idx++) {
            int iCheck = toBeChecked.at(idx);
            BRepBuilderAPI_MakeFace mkFace2(sortedWires.at(iCheck));
            const TopoDS_Face& face2 = mkFace2.Face();
            BRepGProp::SurfaceProperties(face2, props);
            double area = props.Mass();
            if (area > bigArea) {
                bigArea = area;
                bigIndex = iCheck;
            }
        }
        if (bigIndex == 0) {                    //first wire is the biggest
            if (!includeBiggest) {
                sortedWires.erase(sortedWires.begin());
            }
        } else {                                  //first wire is not the biggest
            TopoDS_Wire bigWire = *(sortedWires.begin() + bigIndex);
            sortedWires.erase(sortedWires.begin() + bigIndex);
            if (includeBiggest) {
                sortedWires.insert(sortedWires.begin(),bigWire);               //doesn't happen often
            }
        }

    }
    return sortedWires;
}