/*static*/
BaseGeomPtrVector GeometryUtils::chainGeoms(BaseGeomPtrVector geoms)
{
    BaseGeomPtrVector result;
    std::vector<bool> used(geoms.size(),false);

    if (geoms.empty()) {
        return result;
    }

    if (geoms.size() == 1) {
        //don't bother for single geom (circles, ellipses,etc)
        result.push_back(geoms[0]);
    } else {
        //start with first edge
        result.push_back(geoms[0]);
        Base::Vector2d atPoint = (geoms[0])->getEndPoint();
        used[0] = true;
        for (unsigned int i = 1; i < geoms.size(); i++) { //do size-1 more edges
            auto next( nextGeom(atPoint, geoms, used, Precision::Confusion()) );
            if (next.index) { //found an unused edge with vertex == atPoint
                BaseGeom* nextEdge = geoms.at(next.index);
                used[next.index] = true;
                nextEdge->reversed = next.reversed;
                result.push_back(nextEdge);
                if (next.reversed) {
                    atPoint = nextEdge->getStartPoint();
                } else {
                    atPoint = nextEdge->getEndPoint();
                }
            } else {
                Base::Console().Log("Error - Geometry::chainGeoms - couldn't find next edge\n");
                //TARFU
            }
        }
    }
    return result;
}
//! update edgeGeom and vertexGeom from Compound of edges
void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass category, bool visible)
{
    if(edgeCompound.IsNull()) {
        Base::Console().Log("TechDraw::GeometryObject::addGeomFromCompound edgeCompound is NULL\n");
        return; // There is no OpenCascade Geometry to be calculated
    }

    BaseGeom* base;
    TopExp_Explorer edges(edgeCompound, TopAbs_EDGE);
    for (int i = 1 ; edges.More(); edges.Next(),i++) {
        const TopoDS_Edge& edge = TopoDS::Edge(edges.Current());
        if (edge.IsNull()) {
            //Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is NULL\n",i);
            continue;
        }
        if (DrawUtil::isZeroEdge(edge)) {
            Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is zeroEdge\n",i);
            continue;
        }

        base = BaseGeom::baseFactory(edge);
        if (base == nullptr) {
            Base::Console().Message("Error - GO::addGeomFromCompound - baseFactory failed for edge: %d\n",i);
            throw Base::Exception("GeometryObject::addGeomFromCompound - baseFactory failed");
        }
        base->classOfEdge = category;
        base->visible = visible;
        edgeGeom.push_back(base);

        //add vertices of new edge if not already in list
        if (visible) {
            BaseGeom* lastAdded = edgeGeom.back();
            bool v1Add = true, v2Add = true;
            bool c1Add = true;
            TechDrawGeometry::Vertex* v1 = new TechDrawGeometry::Vertex(lastAdded->getStartPoint());
            TechDrawGeometry::Vertex* v2 = new TechDrawGeometry::Vertex(lastAdded->getEndPoint());
            TechDrawGeometry::Circle* circle = dynamic_cast<TechDrawGeometry::Circle*>(lastAdded);
            TechDrawGeometry::Vertex* c1 = nullptr;
            if (circle) {
                c1 = new TechDrawGeometry::Vertex(circle->center);
                c1->isCenter = true;
                c1->visible = true;
            }

            std::vector<Vertex *>::iterator itVertex = vertexGeom.begin();
            for (; itVertex != vertexGeom.end(); itVertex++) {
                if ((*itVertex)->isEqual(v1,Precision::Confusion())) {
                    v1Add = false;
                }
                if ((*itVertex)->isEqual(v2,Precision::Confusion())) {
                    v2Add = false;
                }
                if (circle) {
                    if ((*itVertex)->isEqual(c1,Precision::Confusion())) {
                        c1Add = false;
                    }
                }

            }
            if (v1Add) {
                vertexGeom.push_back(v1);
                v1->visible = true;
            } else {
                delete v1;
            }
            if (v2Add) {
                vertexGeom.push_back(v2);
                v2->visible = true;
            } else {
                delete v2;
            }

            if (circle) {
                if (c1Add) {
                    vertexGeom.push_back(c1);
                    c1->visible = true;
                } else {
                    delete c1;
                }
            }
        }
    }  //end TopExp
}
Beispiel #3
0
//! update edgeGeom and vertexGeom from Compound of edges
void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass category, bool visible)
{
    if(edgeCompound.IsNull()) {
        Base::Console().Log("TechDraw::GeometryObject::addGeomFromCompound edgeCompound is NULL\n");
        return; // There is no OpenCascade Geometry to be calculated
    }

    // build a mesh to explore the shape
    //BRepMesh_IncrementalMesh(edgeCompound, Tolerance);    //TODO: is this needed? no idea why we need to mesh shape doesn't seem to change anything

    // Explore all edges of edgeCompound and calculate base geometry representation
    BaseGeom* base;
    TopExp_Explorer edges(edgeCompound, TopAbs_EDGE);
    for (int i = 1 ; edges.More(); edges.Next(),i++) {
        const TopoDS_Edge& edge = TopoDS::Edge(edges.Current());
        if (edge.IsNull()) {
            Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is NULL\n",i);
            continue;
        }
        base = BaseGeom::baseFactory(edge);
        base->classOfEdge = category;
        base->visible = visible;
        edgeGeom.push_back(base);

        //add vertices of new edge if not already in list
        if (visible) {
            BaseGeom* lastAdded = edgeGeom.back();
            //if (edgeGeom.empty()) {horrible_death();} //back() undefined behavior (can't happen? baseFactory always returns a Base?)
            bool v1Add = true, v2Add = true;
            bool c1Add = true;
            TechDrawGeometry::Vertex* v1 = new TechDrawGeometry::Vertex(lastAdded->getStartPoint());
            TechDrawGeometry::Vertex* v2 = new TechDrawGeometry::Vertex(lastAdded->getEndPoint());
            TechDrawGeometry::Circle* circle = dynamic_cast<TechDrawGeometry::Circle*>(lastAdded);
            TechDrawGeometry::Vertex* c1 = nullptr;
            if (circle) {
                c1 = new TechDrawGeometry::Vertex(circle->center);
                c1->isCenter = true;
                c1->visible = true;
            }

            std::vector<Vertex *>::iterator itVertex = vertexGeom.begin();
            for (; itVertex != vertexGeom.end(); itVertex++) {
                if ((*itVertex)->isEqual(v1,Precision::Confusion())) {
                    v1Add = false;
                }
                if ((*itVertex)->isEqual(v2,Precision::Confusion())) {
                    v2Add = false;
                }
                if (circle) {
                    if ((*itVertex)->isEqual(c1,Precision::Confusion())) {
                        c1Add = false;
                    }
                }

            }
            if (v1Add) {
                vertexGeom.push_back(v1);
                v1->visible = true;
            } else {
                delete v1;
            }
            if (v2Add) {
                vertexGeom.push_back(v2);
                v2->visible = true;
            } else {
                delete v2;
            }

            if (circle) {
                if (c1Add) {
                    vertexGeom.push_back(c1);
                    c1->visible = true;
                } else {
                    delete c1;
                }
            }
        }
    }
}