Login  Register

Segmentation fault in RS_EntityContainer::optimizeContours()

Posted by Erik on Apr 19, 2012; 7:15am
URL: https://forum.librecad.org/Segmentation-fault-in-RS-EntityContainer-optimizeContours-tp5651061.html

Hello,

on loading my librecad-project (see 20120418_Dachstudio.dxf) I got a segmentation fault in method optimizeContours().


   :
SS-SL-LR
8
62
256
62
370
-1
370
6
ByLayer
6
100
AcDbEntity
100
100
AcDbHatch
100
10
0
10
20
0
20
30
0
30
210
0
210
220
0
220
230
1
230
2
SOLID
2
70
1
70
71
0
71
91
1
91
92
1
92
93
4
93
72
1
72
10
9972
10
20
861.5
20
11
9972
11
21
856.5
21
72
1
72
10
9972
10
20
856.5
20
11
9963
11
21
856.5
21
72
1
72
10
9963
10
20
856.5
20
11
9963
11
21
861.5
21
72
1
72
10
9963
10
20
861.5
20
11
9972
11
21
861.5
21
97
0
97
75
0
75
76
1
76
98
0
98
0
HATCH
0
HATCH
Speicherzugriffsfehler (segmenation fault)


I've the same problem with the git-hub-version form 18-04-2012 and the latest ubuntu 11.04 version (2.0.0~alpha2+yeslib20121041136.693+20120416+cc440c9-0ubuntu0~daily7~natty1, 2.0.0~alpha2+yeslib20121041136.693+20120417+cc440c9-0ubuntu0~daily7~natty1).

I find out, that there is no handling for the case next is an pointer to NULL. This NULL pointer comes from the instuction getNearestEndpoint(vpEnd,&dist,&next);.

May be there is a bug with saving a project in an earlier version, too.

For me a the moment I fixed it quick and dirty (see marked lines).
If next is NULL, I exit the count()-loop. Hopefully there is no Problem with other contexts, because of this soulution.

**
 * 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

 * to do: find closed contour by flood-fill
 */
bool RS_EntityContainer::optimizeContours() {
//    std::cout<<"RS_EntityContainer::optimizeContours: begin"<<std::endl;

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

    RS_EntityContainer tmp;
    tmp.setAutoUpdateBorders(false);
    bool closed=true;

    /** accept all full circles **/
    QList<RS_Entity*> enList;
    for (uint ci=0; ci<count(); ++ci) {
        RS_Entity* e1=entityAt(ci);
        if (!e1->isEdge() || e1->isContainer() ) {
            enList<<e1;
            continue;
        }
        if(e1->rtti()==RS2::EntityCircle) {
            //directly detect circles, bug#3443277
            tmp.addEntity(e1->clone());
            enList<<e1;
            continue;
        }
    }
    //    std::cout<<"RS_EntityContainer::optimizeContours: 1"<<std::endl;

    const auto itEnd=enList.end();
    for(auto it=enList.begin();it!=itEnd;it++){
        removeEntity(*it);
    }

    /** check and form a closed contour **/
//    std::cout<<"RS_EntityContainer::optimizeContours: 2"<<std::endl;
    /** the first entity **/
    RS_Entity* current(NULL);
    if(count()>0) {
        current=entityAt(0)->clone();
        tmp.addEntity(current);
        removeEntity(entityAt(0));
    }else return false;
//    std::cout<<"RS_EntityContainer::optimizeContours: 3"<<std::endl;
    RS_Vector vpStart;
    RS_Vector vpEnd;
    if(current!=NULL){
        vpStart=current->getStartpoint();
        vpEnd=current->getEndpoint();
    }
        RS_Entity* next(NULL);
//    std::cout<<"RS_EntityContainer::optimizeContours: 4"<<std::endl;
    /** connect entities **/
    while(count()>0){
        double dist(0.);
        getNearestEndpoint(vpEnd,&dist,&next);
        if(dist>1e-4) {
            if(vpEnd.squaredTo(vpStart)<1e-8){
                RS_Entity* e2=entityAt(0);
                tmp.addEntity(e2->clone());
                vpStart=e2->getStartpoint();
                vpEnd=e2->getEndpoint();
                removeEntity(e2);
                continue;
            }
            closed=false;
        }
if (next) { // my workaround
        if(vpEnd.squaredTo(next->getStartpoint())<1e-8){
            vpEnd=next->getEndpoint();
        }else{
            vpEnd=next->getStartpoint();
        }
        next->setProcessed(true);
        tmp.addEntity(next->clone());
         removeEntity(next);
}else{       // my workaround
  closed=false;  // my workaround
  break;           // my workaround
}                    // my workaround
    }
    if( vpEnd.squaredTo(vpStart)>1e-8) closed=false;
//    std::cout<<"RS_EntityContainer::optimizeContours: 5"<<std::endl;


    // add new sorted entities:
    for (RS_Entity* en=tmp.firstEntity(); en!=NULL; en=tmp.nextEntity()) {
        en->setProcessed(false);
        addEntity(en->clone());
    }
//    std::cout<<"RS_EntityContainer::optimizeContours: 6"<<std::endl;

    RS_DEBUG->print("RS_EntityContainer::optimizeContours: OK");
//    std::cout<<"RS_EntityContainer::optimizeContours: end: count()="<<count()<<std::endl;
//    std::cout<<"RS_EntityContainer::optimizeContours: closed="<<closed<<std::endl;
    return closed;
}

Maybe there is a problem with the count()-method, too.

Best Regards

Erik
(From Germany)

P.S.: First I want to open a bug-request, but it isn't allowed to do this as anonymous. How can I register for bug-reports ?)