Пример #1
0
void Plugin_Entity::getPolylineData(QList<Plug_VertexData> *data){
    if (entity == NULL) return;
    RS2::EntityType et = entity->rtti();
    if (et != RS2::EntityPolyline) return;
    RS_Polyline *l = static_cast<RS_Polyline*>(entity);

    RS_Entity* nextEntity = 0;
    RS_AtomicEntity* ae = NULL;
    RS_Entity* v = l->firstEntity(RS2::ResolveNone);
    double bulge=0.0;
//bad polyline without vertex
    if (v == NULL) return;

//First polyline vertex
    if (v->rtti() == RS2::EntityArc) {
        bulge = ((RS_Arc*)v)->getBulge();
    }
    ae = (RS_AtomicEntity*)v;
    data->append(Plug_VertexData(QPointF(ae->getStartpoint().x,
                                         ae->getStartpoint().y),bulge));

    for (v=l->firstEntity(RS2::ResolveNone); v!=NULL; v=nextEntity) {
        nextEntity = l->nextEntity(RS2::ResolveNone);
        bulge = 0.0;
        if (!v->isAtomic()) {
            continue;
        }
        ae = (RS_AtomicEntity*)v;

        if (nextEntity!=NULL) {
            if (nextEntity->rtti()==RS2::EntityArc) {
                bulge = ((RS_Arc*)nextEntity)->getBulge();
            }
        }

        if (l->isClosed()==false || nextEntity!=NULL) {
            data->append(Plug_VertexData(QPointF(ae->getEndpoint().x,
                                         ae->getEndpoint().y),bulge));
        }
    }

}
Пример #2
0
/**
 * Selects all entities that are connected to the given entity.
 *
 * @param e The entity where the algorithm starts. Must be an atomic entity.
 */
void RS_Selection::selectContour(RS_Entity* e) {

    if (e==NULL) {
        return;
    }

    if (!e->isAtomic()) {
        return;
    }

    bool select = !e->isSelected();
    RS_AtomicEntity* ae = (RS_AtomicEntity*)e;
    RS_Vector p1 = ae->getStartpoint();
    RS_Vector p2 = ae->getEndpoint();
    bool found = false;

    // (de)select 1st entity:
    if (graphicView!=NULL) {
        graphicView->deleteEntity(e);
    }
    e->setSelected(select);
    if (graphicView!=NULL) {
        graphicView->drawEntity(e);
    }

    do {
        found = false;

        for (RS_Entity* en=container->firstEntity(); en!=NULL;
                en=container->nextEntity()) {
        //for (uint i=0; i<container->count(); ++i) {
            //RS_Entity* en = container->entityAt(i);

            if (en!=NULL && en->isVisible() && 
				en->isAtomic() && en->isSelected()!=select && 
				(en->getLayer()==NULL || en->getLayer()->isLocked()==false)) {

                ae = (RS_AtomicEntity*)en;
                bool doit = false;

                // startpoint connects to 1st point
                if (ae->getStartpoint().distanceTo(p1)<1.0e-4) {
                    doit = true;
                    p1 = ae->getEndpoint();
                }

                // endpoint connects to 1st point
                else if (ae->getEndpoint().distanceTo(p1)<1.0e-4) {
                    doit = true;
                    p1 = ae->getStartpoint();
                }

                // startpoint connects to 2nd point
                else if (ae->getStartpoint().distanceTo(p2)<1.0e-4) {
                    doit = true;
                    p2 = ae->getEndpoint();
                }

                // endpoint connects to 1st point
                else if (ae->getEndpoint().distanceTo(p2)<1.0e-4) {
                    doit = true;
                    p2 = ae->getStartpoint();
                }

                if (doit) {
                    if (graphicView!=NULL) {
                        graphicView->deleteEntity(ae);
                    }
                    ae->setSelected(select);
                    if (graphicView!=NULL) {
                        graphicView->drawEntity(ae);
                    }
                    found = true;
                }
            }
        }
    } while(found);
}
/**
 * Rearranges the atomic entities in this container in a way that connected
 * entities are stored in the right order and direction.
 * Non-recoursive. Only affects atomic entities in this container.
 *
 * @retval true all contours were closed
 * @retval false at least one contour is not closed
 */
bool RS_ActionPolylineSegment::convertPolyline(RS_Entity* selectedEntity) {

        RS_DEBUG->print("RS_ActionPolylineSegment::convertPolyline");

        RS_Vector current(false);
        RS_Vector start(false);
        RS_Vector end(false);
        RS_EntityContainer tmp;

        bool closed = true;

        int pos = container->findEntity(selectedEntity);
        RS_Entity* e1=container->entityAt(pos);
        if (!e1) return false;

        if (document!=NULL) {
                document->startUndoCycle();
        }
        if (document!=NULL) {
                if (e1!=NULL && e1->isEdge() && !e1->isContainer() &&
                                        !e1->isProcessed()) {

                        RS_AtomicEntity* ce = (RS_AtomicEntity*)e1;

///////////////////////////////////////////////////
                        ce->setUndoState(true);
                        document->addUndoable(ce);
///////////////////////////////////////////////////

                        // next contour start:
                        ce->setProcessed(true);
                        tmp.addEntity(ce->clone());
                        current = ce->getStartpoint();
                        end = ce->getEndpoint();

                        // find first connected entities:
                        for (int ei=pos-1; ei>=0; --ei) {
                                RS_Entity* e2=container->entityAt(ei);

                                if (e2!=NULL && e2->isEdge() && !e2->isContainer() &&
                                                !e2->isProcessed()) {

                                        RS_AtomicEntity* e = (RS_AtomicEntity*)e2;
///////////////////////////////////////////////////
                                        e->setUndoState(true);
                                        document->addUndoable(e);
///////////////////////////////////////////////////
                                        if (e->getEndpoint().distanceTo(current) <
                                                        1.0e-4) {
                                                e->setProcessed(true);
                                                tmp.insertEntity(0,e->clone());
                                                current = e->getStartpoint();
                                        } else if (e->getStartpoint().distanceTo(current) <
                                                           1.0e-4) {
                                                e->setProcessed(true);
                                                RS_AtomicEntity* cl = (RS_AtomicEntity*)e->clone();
                                                cl->reverse();
                                                tmp.insertEntity(0,cl);
                                                current = cl->getStartpoint();
                                        }else
                                                break;
                                }
                        }

                        if (current.distanceTo(end)>1.0e-4) {
                                closed = false;
                        }

                        current = ce->getEndpoint();
                        start = ce->getStartpoint();
                        // find last connected entities:
                        for (uint ei=pos+1; ei<container->count(); ++ei) {
                                RS_Entity* e2=container->entityAt(ei);
///////////////////////////////////////////////////
                                e2->setUndoState(true);
                                document->addUndoable(e2);
///////////////////////////////////////////////////
                                if (e2!=NULL && e2->isEdge() && !e2->isContainer() &&
                                                !e2->isProcessed()) {
                                        RS_AtomicEntity* e = (RS_AtomicEntity*)e2;
                                        if (e->getStartpoint().distanceTo(current) <
                                                        1.0e-4) {
                                                e->setProcessed(true);
                                                tmp.addEntity(e->clone());
                                                current = e->getEndpoint();
                                        } else if (e->getEndpoint().distanceTo(current) <
                                                           1.0e-4) {
                                                e->setProcessed(true);
                                                RS_AtomicEntity* cl = (RS_AtomicEntity*)e->clone();
                                                cl->reverse();
                                                tmp.addEntity(cl);
                                                current = cl->getEndpoint();
                                        }else
                                                break;
                                }
                        }
                        if (current.distanceTo(start)>1.0e-4) {
                                closed = false;
                        }
                }
        }
        if (document!=NULL) {
                document->endUndoCycle();
        }

        RS_Polyline* newPolyline = new RS_Polyline(container, RS_PolylineData(RS_Vector(false), RS_Vector(false), closed));
        newPolyline->setLayerToActive();
        newPolyline->setPenToActive();
        // add new polyline:
        bool first = true;
        RS_Entity* lastEntity = tmp.lastEntity();
        for (RS_Entity* en=tmp.firstEntity(); en!=NULL; en=tmp.nextEntity()) {
                en->setProcessed(false);
                double bulge = 0.0;
                if (en->rtti()==RS2::EntityArc) {
                        bulge = ((RS_Arc*)en)->getBulge();
                } else {
                        bulge = 0.0;
                }
                if (first) {
                        newPolyline->setNextBulge(bulge);
                        newPolyline->addVertex(((RS_AtomicEntity*)en)->getStartpoint());
                        first = false;
                }
                if (en!=lastEntity || closed==false){
                        newPolyline->setNextBulge(bulge);
                        newPolyline->addVertex(((RS_AtomicEntity*)en)->getEndpoint());
                }
        }
        double bulge = lastEntity->rtti() == RS2::EntityArc? ((RS_Arc*)lastEntity)->getBulge():0.0;
        newPolyline->setNextBulge(bulge);
        newPolyline->endPolyline();
        container->addEntity(newPolyline);

        if (graphicView!=NULL) {
                graphicView->drawEntity(newPolyline);
        }

        if (document!=NULL) {
                document->startUndoCycle();
                document->addUndoable(newPolyline);
                document->endUndoCycle();
        }
        RS_DEBUG->print("RS_ActionPolylineSegment::convertPolyline: OK");
        return closed;
}
Пример #4
0
/**
 * Rearranges the atomic entities in this container in a way that connected
 * entities are stored in the right order and direction.
 * Non-recoursive. Only affects atomic entities in this container.
 * 
 * @retval true all contours were closed
 * @retval false at least one contour is not closed
 */
bool RS_EntityContainer::optimizeContours() {

    RS_DEBUG->print("RS_EntityContainer::optimizeContours");

    RS_Vector current(false);
    RS_Vector start(false);
    RS_EntityContainer tmp;

    bool changed = false;
    bool closed = true;

    for (uint ci=0; ci<count(); ++ci) {
        RS_Entity* e1=entityAt(ci);

        if (e1!=NULL && e1->isEdge() && !e1->isContainer() &&
                !e1->isProcessed()) {

            RS_AtomicEntity* ce = (RS_AtomicEntity*)e1;

            // next contour start:
            ce->setProcessed(true);
            tmp.addEntity(ce->clone());
            current = ce->getEndpoint();
            start = ce->getStartpoint();

            // find all connected entities:
            bool done;
            do {
                done = true;
                for (uint ei=0; ei<count(); ++ei) {
                    RS_Entity* e2=entityAt(ei);

                    if (e2!=NULL && e2->isEdge() && !e2->isContainer() &&
                            !e2->isProcessed()) {

                        RS_AtomicEntity* e = (RS_AtomicEntity*)e2;

                        if (e->getStartpoint().distanceTo(current) <
                                1.0e-4) {

                            e->setProcessed(true);
                            tmp.addEntity(e->clone());
                            current = e->getEndpoint();

                            done=false;
                        } else if (e->getEndpoint().distanceTo(current) <
                                   1.0e-4) {

                            e->setProcessed(true);
                            RS_AtomicEntity* cl = (RS_AtomicEntity*)e->clone();
                            cl->reverse();
                            tmp.addEntity(cl);
                            current = cl->getEndpoint();

                            changed = true;
                            done=false;
                        }
                    }
                }
                if (!done) {
                    changed = true;
                }
            } while (!done);

            if (current.distanceTo(start)>1.0e-4) {
                closed = false;
            }
        }
    }

    // remove all atomic entities:
    bool done;
    do {
        done = true;
        for (RS_Entity* en=firstEntity(); en!=NULL; en=nextEntity()) {
            if (!en->isContainer()) {
                removeEntity(en);
                done = false;
                break;
            }
        }
    } while (!done);

    // add new sorted entities:
    for (RS_Entity* en=tmp.firstEntity(); en!=NULL; en=tmp.nextEntity()) {
        en->setProcessed(false);
        addEntity(en->clone());
    }

    RS_DEBUG->print("RS_EntityContainer::optimizeContours: OK");
    return closed;
}