示例#1
0
void CmdTechDrawNewHatch::activated(int iMsg)
{
    if (!_checkSelectionHatch(this)) {
        return;
    }

    std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
    TechDraw::DrawViewPart * objFeat = dynamic_cast<TechDraw::DrawViewPart *>(selection[0].getObject());
    const std::vector<std::string> &subNames = selection[0].getSubNames();
    TechDraw::DrawPage* page = objFeat->findParentPage();
    std::string PageName = page->getNameInDocument();

    TechDraw::DrawHatch *hatch = 0;
    std::string FeatName = getUniqueObjectName("Hatch");
    std::stringstream featLabel;
    featLabel << FeatName << "F" << TechDraw::DrawUtil::getIndexFromName(subNames.at(0));

    openCommand("Create Hatch");
    doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawHatch','%s')",FeatName.c_str());
    doCommand(Doc,"App.activeDocument().%s.Label = '%s'",FeatName.c_str(),featLabel.str().c_str());

    hatch = dynamic_cast<TechDraw::DrawHatch *>(getDocument()->getObject(FeatName.c_str()));
    hatch->Source.setValue(objFeat, subNames);
    //should this be: doCommand(Doc,"App..Feat..Source = [(App...%s,%s),(App..%s,%s),...]",objs[0]->getNameInDocument(),subs[0],...);
    //seems very unwieldy

    commitCommand();

    //Horrible hack to force Tree update  ??still required??
    double x = objFeat->X.getValue();
    objFeat->X.setValue(x);
    getDocument()->recompute();
}
示例#2
0
void DrawViewSection::unsetupObject()
{
    TechDraw::DrawViewPart* base = getBaseDVP();
    if (base != nullptr) {
        base->touch();
    }
    DrawViewPart::unsetupObject();
}
示例#3
0
void QGIViewPart::updateView(bool update)
{
    if (getViewObject() == 0 ||
        !getViewObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
        return;
    }

    QGIView::updateView(update);

    TechDraw::DrawViewPart *viewPart = dynamic_cast<TechDraw::DrawViewPart *>(getViewObject());

    if (update ||
       viewPart->isTouched() ||
       viewPart->Source.isTouched() ||
       viewPart->Direction.isTouched() ||
       viewPart->XAxisDirection.isTouched() ||
       viewPart->Tolerance.isTouched() ||
       viewPart->Scale.isTouched() ||
       viewPart->ShowHiddenLines.isTouched() ||
       viewPart->ShowSmoothLines.isTouched() ||
       viewPart->ShowSeamLines.isTouched() ) {
        // Remove all existing graphical representations (QGIxxxx)  otherwise BRect only grows, never shrinks?
        // is this where selection messes up?
        prepareGeometryChange();
        QList<QGraphicsItem*> items = childItems();
        for(QList<QGraphicsItem*>::iterator it = items.begin(); it != items.end(); ++it) {
            if (dynamic_cast<QGIEdge *> (*it) ||
                dynamic_cast<QGIFace *>(*it) ||
                dynamic_cast<QGIVertex *>(*it)) {
                removeFromGroup(*it);
                scene()->removeItem(*it);

                // We store these and delete till later to prevent rendering crash ISSUE
                deleteItems.append(*it);
            }
        }
        draw();
    } else if (update ||
              viewPart->LineWidth.isTouched() ||
              viewPart->HiddenWidth.isTouched()) {
        QList<QGraphicsItem*> items = childItems();
        for(QList<QGraphicsItem*>::iterator it = items.begin(); it != items.end(); ++it) {
            QGIEdge *edge = dynamic_cast<QGIEdge *>(*it);
            if(edge  && edge->getHiddenEdge()) {
                edge->setStrokeWidth(viewPart->HiddenWidth.getValue() * lineScaleFactor);
            } else {
                edge->setStrokeWidth(viewPart->LineWidth.getValue() * lineScaleFactor);
            }
        }
        draw();
    } else {
        QGIView::draw();
    }
}
示例#4
0
void CmdTechDrawNewViewSection::activated(int iMsg)
{
    Q_UNUSED(iMsg);
    //TODO: should just use BaseView's page
    TechDraw::DrawPage* page = _findPage(this);
    if (!page) {
        return;
    }

    //std::vector<App::DocumentObject*> shapes = getSelection().getObjectsOfType(Part::Feature::getClassTypeId());
    std::vector<App::DocumentObject*> shapes = getSelection().getObjectsOfType(TechDraw::DrawViewPart::getClassTypeId());
    if (shapes.empty()) {
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
            QObject::tr("Select at least 1 DrawingView object."));
        return;
    }
    App::DocumentObject* dObj = *(shapes.begin());
    TechDraw::DrawViewPart* dvp = static_cast<TechDraw::DrawViewPart*>(dObj);
    if (dvp->getSectionRef()) {
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
            QObject::tr("This View already has a related Section. Choose another."));
        return;
    }

    std::string PageName = page->getNameInDocument();

    Gui::WaitCursor wc;
    openCommand("Create view");

    std::string FeatName = getUniqueObjectName("Section");
    std::string SourceName = dvp->Source.getValue()->getNameInDocument();
    doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewSection','%s')",FeatName.c_str());
    doCommand(Doc,"App.activeDocument().%s.Source = App.activeDocument().%s",FeatName.c_str(),SourceName.c_str());
    doCommand(Doc,"App.activeDocument().%s.BaseView = App.activeDocument().%s",FeatName.c_str(),(dObj)->getNameInDocument());
    doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str());
    App::DocumentObject *docObj = getDocument()->getObject(FeatName.c_str());
    TechDraw::DrawViewSection* dsv = dynamic_cast<TechDraw::DrawViewSection *>(docObj);
    if (!dsv) {
        throw Base::Exception("CmdTechDrawNewViewSection DSV not found\n");
    }
    Gui::Control().showDialog(new TaskDlgSectionView(dvp,dsv));

    updateActive();
    commitCommand();
}
示例#5
0
void DrawPage::onDocumentRestored()
{
    std::vector<App::DocumentObject*> featViews = Views.getValues();
    std::vector<App::DocumentObject*>::const_iterator it = featViews.begin();
    //first, make sure all the Parts have been executed so GeometryObjects exist
    for(; it != featViews.end(); ++it) {
        TechDraw::DrawViewPart *part = dynamic_cast<TechDraw::DrawViewPart *>(*it);
        if (part != NULL) {
            part->execute();
        }
    }
    //second, make sure all the Dimensions have been executed so Measurements have References
    for(it = featViews.begin(); it != featViews.end(); ++it) {
        TechDraw::DrawViewDimension *dim = dynamic_cast<TechDraw::DrawViewDimension *>(*it);
        if (dim != NULL) {
            dim->execute();
        }
    }
    recompute();
    App::DocumentObject::onDocumentRestored();
}
示例#6
0
double DrawViewDimension::getDimValue() const
{
    double result = 0.0;
    if (!has2DReferences()) {                                            //happens during Dimension creation
        Base::Console().Message("INFO - DVD::getDimValue - Dimension has no References\n");
        return result;
    }

    if (!getViewPart()->hasGeometry()) {                              //happens when loading saved document
        Base::Console().Message("INFO - DVD::getDimValue ViewPart has no Geometry yet\n");
        return result;
    }

    if (MeasureType.isValue("True")) {
        // True Values
        if (!measurement->has3DReferences()) {
            return result;
        }
        if(Type.isValue("Distance")) {
            result = measurement->delta().Length();
        } else if(Type.isValue("DistanceX")){
            Base::Vector3d delta = measurement->delta();
            result = delta.x;
        } else if(Type.isValue("DistanceY")){
            Base::Vector3d delta = measurement->delta();
            result = delta.y;
        } else if(Type.isValue("DistanceZ")){
            Base::Vector3d delta = measurement->delta();
            result = delta.z;
        } else if(Type.isValue("Radius")){
            result =  measurement->radius();
        } else if(Type.isValue("Diameter")){
            result =  measurement->radius() * 2.0;
        } else if(Type.isValue("Angle")){
            result = measurement->angle();
        } else {
            throw Base::Exception("getDimValue() - Unknown Dimension Type (1)");
        }
    } else {
        // Projected Values
        const std::vector<App::DocumentObject*> &objects = References2D.getValues();
        const std::vector<std::string> &subElements      = References2D.getSubValues();
        if (Type.isValue("Distance") && getRefType() == oneEdge) {
            //TODO: Check for straight line Edge?
            int idx = DrawUtil::getIndexFromName(subElements[0]);
            TechDrawGeometry::BaseGeom* geom = getViewPart()->getProjEdgeByIndex(idx);
            TechDrawGeometry::Generic* gen = static_cast<TechDrawGeometry::Generic*>(geom);
            Base::Vector2D start = gen->points[0];
            Base::Vector2D end = gen->points[1];
            Base::Vector2D line = end - start;
            result = line.Length() / getViewPart()->Scale.getValue();
        } else if (Type.isValue("Distance") && getRefType() == twoEdge) {
            //only works for straight line edges
            int idx0 = DrawUtil::getIndexFromName(subElements[0]);
            int idx1 = DrawUtil::getIndexFromName(subElements[1]);
            TechDrawGeometry::BaseGeom* geom0 = getViewPart()->getProjEdgeByIndex(idx0);
            TechDrawGeometry::BaseGeom* geom1 = getViewPart()->getProjEdgeByIndex(idx1);
            TechDrawGeometry::Generic* gen0 = static_cast<TechDrawGeometry::Generic*>(geom0);
            TechDrawGeometry::Generic* gen1 = static_cast<TechDrawGeometry::Generic*>(geom1);
            Base::Vector2D s0 = gen0->points[0];
            Base::Vector2D e0 = gen0->points[1];
            Base::Vector2D s1 = gen1->points[0];
            Base::Vector2D e1 = gen1->points[1];
            result = dist2Segs(s0,e0,s1,e1) / getViewPart()->Scale.getValue();
        } else if (Type.isValue("Distance") && getRefType() == twoVertex) {
            int idx0 = DrawUtil::getIndexFromName(subElements[0]);
            int idx1 = DrawUtil::getIndexFromName(subElements[1]);
            TechDrawGeometry::Vertex* v0 = getViewPart()->getProjVertexByIndex(idx0);
            TechDrawGeometry::Vertex* v1 = getViewPart()->getProjVertexByIndex(idx1);
            Base::Vector2D start = v0->pnt;
            Base::Vector2D end = v1->pnt;
            Base::Vector2D line = end - start;
            result = line.Length() / getViewPart()->Scale.getValue();
        } else if (Type.isValue("DistanceX") && getRefType() == oneEdge) {
            int idx = DrawUtil::getIndexFromName(subElements[0]);
            TechDrawGeometry::BaseGeom* geom = getViewPart()->getProjEdgeByIndex(idx);
            TechDrawGeometry::Generic* gen = static_cast<TechDrawGeometry::Generic*>(geom);
            Base::Vector2D start = gen->points[0];
            Base::Vector2D end = gen->points[1];
            Base::Vector2D line = end - start;
            return fabs(line.fX) / getViewPart()->Scale.getValue();
        } else if (Type.isValue("DistanceY") && getRefType() == oneEdge) {
            int idx = DrawUtil::getIndexFromName(subElements[0]);
            TechDrawGeometry::BaseGeom* geom = getViewPart()->getProjEdgeByIndex(idx);
            TechDrawGeometry::Generic* gen = static_cast<TechDrawGeometry::Generic*>(geom);
            Base::Vector2D start = gen->points[0];
            Base::Vector2D end = gen->points[1];
            Base::Vector2D line = end - start;
            result = fabs(line.fY) / getViewPart()->Scale.getValue();
        } else if (Type.isValue("DistanceX") && getRefType() == twoVertex) {
            int idx0 = DrawUtil::getIndexFromName(subElements[0]);
            int idx1 = DrawUtil::getIndexFromName(subElements[1]);
            TechDrawGeometry::Vertex* v0 = getViewPart()->getProjVertexByIndex(idx0);
            TechDrawGeometry::Vertex* v1 = getViewPart()->getProjVertexByIndex(idx1);
            Base::Vector2D start = v0->pnt;
            Base::Vector2D end = v1->pnt;
            Base::Vector2D line = end - start;
            result = fabs(line.fX) / getViewPart()->Scale.getValue();
        } else if (Type.isValue("DistanceY") && getRefType() == twoVertex) {
            int idx0 = DrawUtil::getIndexFromName(subElements[0]);
            int idx1 = DrawUtil::getIndexFromName(subElements[1]);
            TechDrawGeometry::Vertex* v0 = getViewPart()->getProjVertexByIndex(idx0);
            TechDrawGeometry::Vertex* v1 = getViewPart()->getProjVertexByIndex(idx1);
            Base::Vector2D start = v0->pnt;
            Base::Vector2D end = v1->pnt;
            Base::Vector2D line = end - start;
            result = fabs(line.fY) / getViewPart()->Scale.getValue();
        } else if(Type.isValue("Radius")){
            //only 1 reference for a Radius
            int idx = DrawUtil::getIndexFromName(subElements[0]);
            TechDrawGeometry::BaseGeom* base = getViewPart()->getProjEdgeByIndex(idx);
            TechDrawGeometry::Circle* circle = static_cast<TechDrawGeometry::Circle*> (base);
            result = circle->radius / getViewPart()->Scale.getValue();            //Projected BaseGeom is scaled for drawing
        } else if(Type.isValue("Diameter")){
            //only 1 reference for a Diameter
            int idx = DrawUtil::getIndexFromName(subElements[0]);
            TechDrawGeometry::BaseGeom* base = getViewPart()->getProjEdgeByIndex(idx);
            TechDrawGeometry::Circle* circle = static_cast<TechDrawGeometry::Circle*> (base);
            result = (circle->radius  * 2.0) / getViewPart()->Scale.getValue();   //Projected BaseGeom is scaled for drawing
        } else if(Type.isValue("Angle")){
            // Must project lines to 2D so cannot use measurement framework this time
            //Relcalculate the measurement based on references stored.
            //WF: why not use projected geom in GeomObject and Vector2D.GetAngle? intersection pt & direction issues?
            //TODO: do we need to distinguish inner vs outer angle? -wf
//            if(subElements.size() != 2) {
//                throw Base::Exception("FVD - Two references required for angle measurement");
//            }
            if (getRefType() != twoEdge) {
                throw Base::Exception("FVD - Two edge references required for angle measurement");
            }
            int idx0 = DrawUtil::getIndexFromName(subElements[0]);
            int idx1 = DrawUtil::getIndexFromName(subElements[1]);
            TechDraw::DrawViewPart *viewPart = dynamic_cast<TechDraw::DrawViewPart *>(objects[0]);
            TechDrawGeometry::BaseGeom* edge0 = viewPart->getProjEdgeByIndex(idx0);
            TechDrawGeometry::BaseGeom* edge1 = viewPart->getProjEdgeByIndex(idx1);

            // Only can find angles with straight line edges
            if(edge0->geomType == TechDrawGeometry::GENERIC &&
               edge1->geomType == TechDrawGeometry::GENERIC) {
                TechDrawGeometry::Generic *gen1 = static_cast<TechDrawGeometry::Generic *>(edge0);
                TechDrawGeometry::Generic *gen2 = static_cast<TechDrawGeometry::Generic *>(edge1);

                Base::Vector3d p1S(gen1->points.at(0).fX, gen1->points.at(0).fY, 0.);
                Base::Vector3d p1E(gen1->points.at(1).fX, gen1->points.at(1).fY, 0.);

                Base::Vector3d p2S(gen2->points.at(0).fX, gen2->points.at(0).fY, 0.);
                Base::Vector3d p2E(gen2->points.at(1).fX, gen2->points.at(1).fY, 0.);

                Base::Vector3d dir1 = p1E - p1S;
                Base::Vector3d dir2 = p2E - p2S;

                // Line Intersetion (taken from ViewProviderSketch.cpp)
                double det = dir1.x*dir2.y - dir1.y*dir2.x;
                if ((det > 0 ? det : -det) < 1e-10)
                    throw Base::Exception("Invalid selection - Det = 0");

                double c1 = dir1.y*gen1->points.at(0).fX - dir1.x*gen1->points.at(0).fY;
                double c2 = dir2.y*gen2->points.at(1).fX - dir2.x*gen2->points.at(1).fY;
                double x = (dir1.x*c2 - dir2.x*c1)/det;
                double y = (dir1.y*c2 - dir2.y*c1)/det;

                // Intersection point
                Base::Vector3d p0 = Base::Vector3d(x,y,0);

                Base::Vector3d lPos((double) X.getValue(), (double) Y.getValue(), 0.);
                //Base::Vector3d delta = lPos - p0;

                // Create vectors point towards intersection always
                Base::Vector3d a = -p0, b = -p0;
                a += ((p1S - p0).Length() < FLT_EPSILON) ? p1E : p1S;
                b += ((p2S - p0).Length() < FLT_EPSILON) ? p2E : p2S;

                double angle2 = atan2( a.x*b.y - a.y*b.x, a.x*b.x + a.y*b.y );
                result = angle2 * 180. / M_PI;
            } else {
                throw Base::Exception("getDimValue() - Unknown Dimension Type (2)");
            }
        }  //endif Angle
    } //endif Projected
    return result;
}
示例#7
0
void QGIViewPart::drawSectionLine(TechDraw::DrawViewSection* viewSection, bool b)
{
    TechDraw::DrawViewPart *viewPart = static_cast<TechDraw::DrawViewPart *>(getViewObject());
    if (!viewPart ||
        !viewSection)  {
        return;
    }
    if (b) {
        QGISectionLine* sectionLine = new QGISectionLine();
        addToGroup(sectionLine);
        sectionLine->setSymbol(const_cast<char*>(viewSection->SectionSymbol.getValue()));

        //TODO: handle oblique section lines?
        //find smallest internal angle(normalDir,get?Dir()) and use -1*get?Dir() +/- angle
        //Base::Vector3d normalDir = viewSection->SectionNormal.getValue();
        Base::Vector3d arrowDir(0,1,0);                //for drawing only, not geom
        Base::Vector3d lineDir(1,0,0);
        bool horiz = false;
        if (viewSection->SectionDirection.isValue("Right")) {
            arrowDir = Base::Vector3d(1,0,0);
            lineDir = Base::Vector3d(0,1,0);
        } else if (viewSection->SectionDirection.isValue("Left")) {
            arrowDir = Base::Vector3d(-1,0,0);
            lineDir = Base::Vector3d(0,-1,0);
        } else if (viewSection->SectionDirection.isValue("Up")) {
            arrowDir = Base::Vector3d(0,1,0);
            lineDir = Base::Vector3d(1,0,0);
            horiz = true;
        } else if (viewSection->SectionDirection.isValue("Down")) {
            arrowDir = Base::Vector3d(0,-1,0);
            lineDir = Base::Vector3d(-1,0,0);
            horiz = true;
        }
        sectionLine->setDirection(arrowDir.x,arrowDir.y);

        Base::Vector3d org = viewSection->SectionOrigin.getValue();
        double scale = viewPart->Scale.getValue();
        Base::Vector3d pOrg = scale * viewPart->projectPoint(org);
        //pOrg.y = -1 * pOrg.y;
        //now project pOrg onto arrowDir
        Base::Vector3d displace;
        displace.ProjectToLine(pOrg, arrowDir);
        Base::Vector3d offset = pOrg + displace;

        sectionLine->setPos(offset.x,offset.y);
        double sectionSpan;
        double sectionFudge = 10.0;
        double xVal, yVal;
        if (horiz)  {
            sectionSpan = m_border->rect().width() + sectionFudge;
            xVal = sectionSpan / 2.0;
            yVal = 0.0;
        } else {
            sectionSpan = (m_border->rect().height() - m_label->boundingRect().height()) + sectionFudge;
            xVal = 0.0;
            yVal = sectionSpan / 2.0;
        }
        sectionLine->setBounds(-xVal,-yVal,xVal,yVal);
        sectionLine->setWidth(viewPart->LineWidth.getValue());          //TODO: add fudge to make sectionLine thinner than reg lines?
        sectionLine->setFont(m_font,6.0);
        sectionLine->setZValue(ZVALUE::SECTIONLINE);
        sectionLine->draw();
    }
}
示例#8
0
void QGIViewPart::drawViewPart()
{
    if ( getViewObject() == 0 ||
         !getViewObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
        return;
    }

    TechDraw::DrawViewPart *viewPart = dynamic_cast<TechDraw::DrawViewPart *>(getViewObject());

    float lineWidth = viewPart->LineWidth.getValue() * lineScaleFactor;
    float lineWidthHid = viewPart->HiddenWidth.getValue() * lineScaleFactor;

    prepareGeometryChange();

#if MOD_TECHDRAW_HANDLE_FACES
    // Draw Faces
    std::vector<TechDraw::DrawHatch*> hatchObjs = viewPart->getHatches();
    const std::vector<TechDrawGeometry::Face *> &faceGeoms = viewPart->getFaceGeometry();
    std::vector<TechDrawGeometry::Face *>::const_iterator fit = faceGeoms.begin();
    for(int i = 0 ; fit != faceGeoms.end(); fit++, i++) {
        QGIFace* newFace = drawFace(*fit,i);
        TechDraw::DrawHatch* fHatch = faceIsHatched(i,hatchObjs);
        if (fHatch) {
            if (!fHatch->HatchPattern.isEmpty()) {
                App::Color hColor = fHatch->HatchColor.getValue();
                newFace->setHatchColor(hColor.asCSSString());
                newFace->setHatch(fHatch->HatchPattern.getValue());
            }
        }
        newFace->setZValue(ZVALUE::FACE);
        newFace->setPrettyNormal();
    }
#endif //#if MOD_TECHDRAW_HANDLE_FACES

    // Draw Edges
    const std::vector<TechDrawGeometry::BaseGeom *> &geoms = viewPart->getEdgeGeometry();
    std::vector<TechDrawGeometry::BaseGeom *>::const_iterator itEdge = geoms.begin();
    QGIEdge* item;
    for(int i = 0 ; itEdge != geoms.end(); itEdge++, i++) {
        bool showEdge = false;
        if ((*itEdge)->visible) {
            if (((*itEdge)->classOfEdge == ecHARD) ||
                ((*itEdge)->classOfEdge == ecOUTLINE) ||
                (((*itEdge)->classOfEdge == ecSMOOTH) && viewPart->ShowSmoothLines.getValue()) ||
                (((*itEdge)->classOfEdge == ecSEAM) && viewPart->ShowSeamLines.getValue())) {
                showEdge = true;
            }
        } else {
            if (viewPart->ShowHiddenLines.getValue()) {
                showEdge = true;
            }
        }
        if (showEdge) {
            item = new QGIEdge(i);
            addToGroup(item);                                                   //item is at scene(0,0), not group(0,0)
            item->setPos(0.0,0.0);
            item->setPath(drawPainterPath(*itEdge));
            item->setStrokeWidth(lineWidth);
            item->setZValue(ZVALUE::EDGE);
            if(!(*itEdge)->visible) {
                item->setStrokeWidth(lineWidthHid);
                item->setHiddenEdge(true);
                item->setZValue(ZVALUE::HIDEDGE);
            }
            item->setPrettyNormal();
            //debug a path
            //QPainterPath edgePath=drawPainterPath(*itEdge);
            //std::stringstream edgeId;
            //edgeId << "QGIVP.edgePath" << i;
            //dumpPath(edgeId.str().c_str(),edgePath);
         }
    }

    // Draw Vertexs:
    const std::vector<TechDrawGeometry::Vertex *> &verts = viewPart->getVertexGeometry();
    std::vector<TechDrawGeometry::Vertex *>::const_iterator vert = verts.begin();
    for(int i = 0 ; vert != verts.end(); ++vert, i++) {
        QGIVertex *item = new QGIVertex(i);
        addToGroup(item);
        item->setPos((*vert)->pnt.fX, (*vert)->pnt.fY);                //this is in ViewPart coords
        item->setRadius(lineWidth * vertexScaleFactor);
        item->setZValue(ZVALUE::VERTEX);
     }
}
void CmdTechDrawNewAngle3PtDimension::activated(int iMsg)
{
    Q_UNUSED(iMsg);
    bool result = _checkSelection(this,3);
    if (!result)
        return;
    result = _checkDrawViewPart(this);
    if (!result)
        return;

    std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
    TechDraw::DrawViewPart * objFeat = 0;
    std::vector<std::string> SubNames;

    std::vector<Gui::SelectionObject>::iterator itSel = selection.begin();
    for (; itSel != selection.end(); itSel++)  {
        if ((*itSel).getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
            objFeat = static_cast<TechDraw::DrawViewPart*> ((*itSel).getObject());
            SubNames = (*itSel).getSubNames();
        }
    }
    TechDraw::DrawPage* page = objFeat->findParentPage();
    std::string PageName = page->getNameInDocument();

    TechDraw::DrawViewDimension *dim = 0;
    std::string FeatName = getUniqueObjectName("Dimension");

    std::vector<App::DocumentObject *> objs;
    std::vector<std::string> subs;

    if (_isValidVertexes(this, 3))  {
        objs.push_back(objFeat);
        objs.push_back(objFeat);
        objs.push_back(objFeat);
        subs.push_back(SubNames[0]);
        subs.push_back(SubNames[1]);
        subs.push_back(SubNames[2]);
    } else {
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"),
                                                   QObject::tr("Need three points to make an 3 point Angle Dimension"));
        return;
    }

    openCommand("Create Dimension");
    doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')",FeatName.c_str());
    doCommand(Doc,"App.activeDocument().%s.Type = '%s'",FeatName.c_str()
                                                       ,"Angle3Pt");

    dim = dynamic_cast<TechDraw::DrawViewDimension *>(getDocument()->getObject(FeatName.c_str()));
    if (!dim) {
        throw Base::Exception("CmdTechDrawNewAngle3PtDimension - dim not found\n");
    }
    dim->References2D.setValues(objs, subs);

    doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str());

    commitCommand();
    dim->recomputeFeature();

    //Horrible hack to force Tree update
    double x = objFeat->X.getValue();
    objFeat->X.setValue(x);
}
void CmdTechDrawNewDistanceYDimension::activated(int iMsg)
{
    Q_UNUSED(iMsg);
    bool result = _checkSelection(this,2);
    if (!result)
        return;
    result = _checkDrawViewPart(this);
    if (!result)
        return;

    std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
    TechDraw::DrawViewPart * objFeat = 0;
    std::vector<std::string> SubNames;

    std::vector<Gui::SelectionObject>::iterator itSel = selection.begin();
    for (; itSel != selection.end(); itSel++)  {
        if ((*itSel).getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
            objFeat = static_cast<TechDraw::DrawViewPart*> ((*itSel).getObject());
            SubNames = (*itSel).getSubNames();
        }
    }
    TechDraw::DrawPage* page = objFeat->findParentPage();
    std::string PageName = page->getNameInDocument();

    TechDraw::DrawViewDimension *dim = 0;
    std::string FeatName = getUniqueObjectName("Dimension");
    std::string dimType;

    std::vector<App::DocumentObject *> objs;
    std::vector<std::string> subs;

    int edgeType = _isValidSingleEdge(this);
    if ((edgeType == isVertical) ||
        (edgeType == isDiagonal)) {
        objs.push_back(objFeat);
        subs.push_back(SubNames[0]);
    } else if (_isValidVertexes(this)) {
        objs.push_back(objFeat);
        objs.push_back(objFeat);
        subs.push_back(SubNames[0]);
        subs.push_back(SubNames[1]);
    } else if ((_isValidEdgeToEdge(this) == isVertical)   ||
               (_isValidEdgeToEdge(this) == isHorizontal) ||
               (_isValidEdgeToEdge(this) == isDiagonal) ||
               (_isValidEdgeToEdge(this) == isAngle))  {
        edgeType = _isValidEdgeToEdge(this);
        objs.push_back(objFeat);
        objs.push_back(objFeat);
        subs.push_back(SubNames[0]);
        subs.push_back(SubNames[1]);
    } else if (_isValidVertexToEdge(this)) {
        objs.push_back(objFeat);
        objs.push_back(objFeat);
        subs.push_back(SubNames[0]);
        subs.push_back(SubNames[1]);
    } else {
        std::stringstream edgeMsg;
        edgeMsg << "Need 2 Vertexes, 1 straight Edge, 1 Vertex/1 straight edge or 2 straight Edges for Horizontal Dimension (edge type: " << _edgeTypeToText(edgeType) << ")";
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"),
                                                   QObject::tr(edgeMsg.str().c_str()));
        return;
    }

    openCommand("Create Dimension");
    doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')",FeatName.c_str());
    doCommand(Doc,"App.activeDocument().%s.Type = '%s'",FeatName.c_str()
                                                       ,"DistanceY");
    dim = dynamic_cast<TechDraw::DrawViewDimension *>(getDocument()->getObject(FeatName.c_str()));
    if (!dim) {
        throw Base::Exception("CmdTechDrawNewDistanceYDimension - dim not found\n");
    }
    dim->References2D.setValues(objs, subs);

    doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str());

    commitCommand();
    dim->recomputeFeature();
    TechDraw::pointPair pp = dim->getLinearPoints();
    Base::Vector3d mid = (pp.first + pp.second)/2.0;
    dim->X.setValue(mid.x);
    dim->Y.setValue(-mid.y);

    //Horrible hack to force Tree update
    double x = objFeat->X.getValue();
    objFeat->X.setValue(x);
}
void CmdTechDrawNewDiameterDimension::activated(int iMsg)
{
    Q_UNUSED(iMsg);
    bool result = _checkSelection(this,1);
    if (!result)
        return;
    result = _checkDrawViewPart(this);
    if (!result)
        return;

    std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
    TechDraw::DrawViewPart * objFeat = 0;
    std::vector<std::string> SubNames;

    std::vector<Gui::SelectionObject>::iterator itSel = selection.begin();
    for (; itSel != selection.end(); itSel++)  {
        if ((*itSel).getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
            objFeat = static_cast<TechDraw::DrawViewPart*> ((*itSel).getObject());
            SubNames = (*itSel).getSubNames();
        }
    }
    TechDraw::DrawPage* page = objFeat->findParentPage();
    std::string PageName = page->getNameInDocument();

    TechDraw::DrawViewDimension *dim = 0;
    std::string FeatName = getUniqueObjectName("Dimension");

    std::vector<App::DocumentObject *> objs;
    std::vector<std::string> subs;

    int edgeType = _isValidSingleEdge(this);
    if (edgeType == isCircle) {
        objs.push_back(objFeat);
        subs.push_back(SubNames[0]);
    } else if (edgeType == isBSplineCircle) {
        QMessageBox::StandardButton result =
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection Warning"),
                                                   QObject::tr("Selected edge is a BSpline.  Diameter will be approximate."),
                                                   QMessageBox::Ok | QMessageBox::Cancel,
                                                   QMessageBox::Cancel);
        if (result == QMessageBox::Ok) {
            objs.push_back(objFeat);
            subs.push_back(SubNames[0]);
        } else {
            return;
        }
    } else {
        std::stringstream edgeMsg;
        edgeMsg << "Selection for Diameter does not contain a circular edge (edge type: " << _edgeTypeToText(edgeType) << ")";
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"),
                                                   QObject::tr(edgeMsg.str().c_str()));
        return;
    }

    openCommand("Create Dimension");
    doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')",FeatName.c_str());
    doCommand(Doc,"App.activeDocument().%s.Type = '%s'",FeatName.c_str()
                                                       ,"Diameter");

    dim = dynamic_cast<TechDraw::DrawViewDimension *>(getDocument()->getObject(FeatName.c_str()));
    if (!dim) {
        throw Base::Exception("CmdTechDrawNewDiameterDimension - dim not found\n");
    }
    dim->References2D.setValues(objs, subs);

    doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str());

    commitCommand();
    dim->recomputeFeature();

    //Horrible hack to force Tree update
    double x = objFeat->X.getValue();
    objFeat->X.setValue(x);
}
void CmdTechDrawNewDimension::activated(int iMsg)
{
    Q_UNUSED(iMsg);
    bool result = _checkSelection(this,2);
    if (!result)
        return;
    result = _checkDrawViewPart(this);
    if (!result)
        return;

//do we still need to pick DVPs out of selection? or should we complain about junk?
    std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
    TechDraw::DrawViewPart* objFeat = 0;
    std::vector<std::string> SubNames;
    std::vector<Gui::SelectionObject>::iterator itSel = selection.begin();
    for (; itSel != selection.end(); itSel++)  {
        if ((*itSel).getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
            objFeat = static_cast<TechDraw::DrawViewPart*> ((*itSel).getObject());
            SubNames = (*itSel).getSubNames();
        }
    }
    TechDraw::DrawPage* page = objFeat->findParentPage();
    std::string PageName = page->getNameInDocument();

    TechDraw::DrawViewDimension *dim = 0;
    std::string FeatName = getUniqueObjectName("Dimension");
    std::string dimType;

    std::vector<App::DocumentObject *> objs;
    std::vector<std::string> subs;

    int edgeType = _isValidSingleEdge(this);

    if (edgeType) {
        if (edgeType < isCircle) {
            dimType = "Distance";
            objs.push_back(objFeat);
            subs.push_back(SubNames[0]);
        } else if (edgeType == isCircle) {
            dimType = "Radius";
        } else {
            dimType = "Radius";
        }
    } else if (_isValidVertexes(this)) {
        dimType = "Distance";
        objs.push_back(objFeat);
        objs.push_back(objFeat);
        subs.push_back(SubNames[0]);
        subs.push_back(SubNames[1]);
    } else if (_isValidEdgeToEdge(this)) {
        int edgeCase = _isValidEdgeToEdge(this);
        objs.push_back(objFeat);
        objs.push_back(objFeat);
        subs.push_back(SubNames[0]);
        subs.push_back(SubNames[1]);
        switch (edgeCase) {
             case isHorizontal:
                dimType = "DistanceX";
                break;
             case isVertical:
                dimType = "DistanceY";
                break;
            case isDiagonal:
                dimType = "Distance";
                break;
            case isAngle:
                dimType = "Angle";
            default:
                break;
        }
    } else if (_isValidVertexToEdge(this)) {
        dimType = "Distance";
        objs.push_back(objFeat);
        objs.push_back(objFeat);
        subs.push_back(SubNames[0]);
        subs.push_back(SubNames[1]);
    } else {
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"),
                                                   QObject::tr("Can't make a Dimension from this selection"));
        return;
    }

    openCommand("Create Dimension");
    doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewDimension','%s')",FeatName.c_str());
    doCommand(Doc,"App.activeDocument().%s.Type = '%s'",FeatName.c_str()
                                                       ,dimType.c_str());

    dim = dynamic_cast<TechDraw::DrawViewDimension *>(getDocument()->getObject(FeatName.c_str()));
    if (!dim) {
        throw Base::Exception("CmdTechDrawNewDimension - dim not found\n");
    }
    dim->References2D.setValues(objs, subs);

    doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str());
    commitCommand();
    dim->recomputeFeature();

    //Horrible hack to force Tree update
    double x = objFeat->X.getValue();
    objFeat->X.setValue(x);
}