示例#1
0
void Group::AssembleLoops(bool *allClosed,
                          bool *allCoplanar,
                          bool *allNonZeroLen)
{
    SBezierList sbl = {};

    int i;
    for(i = 0; i < SK.entity.n; i++) {
        Entity *e = &(SK.entity.elem[i]);
        if(e->group.v != h.v) continue;
        if(e->construction) continue;
        if(e->forceHidden) continue;

        e->GenerateBezierCurves(&sbl);
    }

    SBezier *sb;
    *allNonZeroLen = true;
    for(sb = sbl.l.First(); sb; sb = sbl.l.NextAfter(sb)) {
        for(i = 1; i <= sb->deg; i++) {
            if(!(sb->ctrl[i]).Equals(sb->ctrl[0])) {
                break;
            }
        }
        if(i > sb->deg) {
            // This is a zero-length edge.
            *allNonZeroLen = false;
            polyError.errorPointAt = sb->ctrl[0];
            goto done;
        }
    }

    // Try to assemble all these Beziers into loops. The closed loops go into
    // bezierLoops, with the outer loops grouped with their holes. The
    // leftovers, if any, go in bezierOpens.
    bezierLoops.FindOuterFacesFrom(&sbl, &polyLoops, NULL,
                                   SS.ChordTolMm(),
                                   allClosed, &(polyError.notClosedAt),
                                   allCoplanar, &(polyError.errorPointAt),
                                   &bezierOpens);
    done:
    sbl.Clear();
}
示例#2
0
void GraphicsWindow::SplitLinesOrCurves(void) {
    if(!LockedInWorkplane()) {
        Error("Must be sketching in workplane to split.");
        return;
    }

    GroupSelection();
    if(!(gs.n == 2 &&(gs.lineSegments +
                      gs.circlesOrArcs + 
                      gs.cubics +
                      gs.periodicCubics) == 2))
    {
        Error("Select two entities that intersect each other (e.g. two lines "
              "or two circles or a circle and a line).");
        return;
    }

    hEntity ha = gs.entity[0],
            hb = gs.entity[1];
    Entity *ea = SK.GetEntity(ha),
           *eb = SK.GetEntity(hb);
   
    // Compute the possibly-rational Bezier curves for each of these entities
    SBezierList sbla, sblb;
    ZERO(&sbla);
    ZERO(&sblb);
    ea->GenerateBezierCurves(&sbla);
    eb->GenerateBezierCurves(&sblb);
    // and then compute the points where they intersect, based on those curves.
    SPointList inters;
    ZERO(&inters);
    sbla.AllIntersectionsWith(&sblb, &inters);

    if(inters.l.n > 0) {
        Vector pi;
        // If there's multiple points, then take the one closest to the
        // mouse pointer.
        double dmin = VERY_POSITIVE;
        SPoint *sp;
        for(sp = inters.l.First(); sp; sp = inters.l.NextAfter(sp)) {
            double d = ProjectPoint(sp->p).DistanceTo(currentMousePosition);
            if(d < dmin) {
                dmin = d;
                pi = sp->p;
            }
        }

        SS.UndoRemember();
        hEntity hia = SplitEntity(ha, pi),
                hib = SplitEntity(hb, pi);
        // SplitEntity adds the coincident constraints to join the split halves
        // of each original entity; and then we add the constraint to join
        // the two entities together at the split point.
        if(hia.v && hib.v) {
            Constraint::ConstrainCoincident(hia, hib);
        }
    } else {
        Error("Can't split; no intersection found.");
    }

    // All done, clean up and regenerate.
    inters.Clear();
    sbla.Clear();
    sblb.Clear();
    ClearSelection();
    SS.later.generateAll = true;
}
示例#3
0
void SolveSpace::ExportViewOrWireframeTo(char *filename, bool wireframe) {
    int i;
    SEdgeList edges;
    ZERO(&edges);
    SBezierList beziers;
    ZERO(&beziers);

    SMesh *sm = NULL;
    if(SS.GW.showShaded) {
        Group *g = SK.GetGroup(SS.GW.activeGroup);
        g->GenerateDisplayItems();
        sm = &(g->displayMesh);
    }
    if(sm && sm->IsEmpty()) {
        sm = NULL;
    }

    for(i = 0; i < SK.entity.n; i++) {
        Entity *e = &(SK.entity.elem[i]);
        if(!e->IsVisible()) continue;
        if(e->construction) continue;

        if(SS.exportPwlCurves || (sm && !SS.GW.showHdnLines) ||
                                 fabs(SS.exportOffset) > LENGTH_EPS)
        {
            // We will be doing hidden line removal, which we can't do on
            // exact curves; so we need things broken down to pwls. Same
            // problem with cutter radius compensation.
            e->GenerateEdges(&edges);
        } else {
            e->GenerateBezierCurves(&beziers);
        }
    }

    if(SS.GW.showEdges) {
        Group *g = SK.GetGroup(SS.GW.activeGroup);
        g->GenerateDisplayItems();
        SEdgeList *selr = &(g->displayEdges);
        SEdge *se;
        for(se = selr->l.First(); se; se = selr->l.NextAfter(se)) {
            edges.AddEdge(se->a, se->b, Style::SOLID_EDGE);
        }
    }

    if(SS.GW.showConstraints) {
        Constraint *c;
        for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
            c->GetEdges(&edges);
        }
    }

    if(wireframe) {
        VectorFileWriter *out = VectorFileWriter::ForFile(filename);
        if(out) {
            ExportWireframeCurves(&edges, &beziers, out);
        }
    } else {
        Vector u = SS.GW.projRight,
               v = SS.GW.projUp,
               n = u.Cross(v),
               origin = SS.GW.offset.ScaledBy(-1);

        VectorFileWriter *out = VectorFileWriter::ForFile(filename);
        if(out) {
            ExportLinesAndMesh(&edges, &beziers, sm,
                               u, v, n, origin, SS.CameraTangent()*SS.GW.scale,
                               out);
        }

        if(out && !out->HasCanvasSize()) {
            // These file formats don't have a canvas size, so they just
            // get exported in the raw coordinate system. So indicate what
            // that was on-screen.
            SS.justExportedInfo.draw = true;
            SS.justExportedInfo.pt = origin;
            SS.justExportedInfo.u = u;
            SS.justExportedInfo.v = v;
            InvalidateGraphics();
        }
    }

    edges.Clear();
    beziers.Clear();
}