Preparatory work for Boolean. Make the u and v coordinates of the
trim curves for all surfaces lie between 0 and 1. And add routines to merge the curves and surfaces from two shells into one, and to split the trim curves into their piecewise linear segments and then reassemble them into trim curves. [git-p4: depot-paths = "//depot/solvespace/": change = 1905]
This commit is contained in:
parent
daba7bf90b
commit
07ddd62a3a
|
@ -177,7 +177,7 @@ done:
|
||||||
runningShell.TriangulateInto(&runningMesh);
|
runningShell.TriangulateInto(&runningMesh);
|
||||||
emphEdges.Clear();
|
emphEdges.Clear();
|
||||||
if(h.v == SS.GW.activeGroup.v && SS.edgeColor != 0) {
|
if(h.v == SS.GW.activeGroup.v && SS.edgeColor != 0) {
|
||||||
thisShell.MakeEdgesInto(&emphEdges);
|
runningShell.MakeEdgesInto(&emphEdges);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ STriangle STriangle::From(STriMeta meta, Vector a, Vector b, Vector c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SEdge SEdge::From(Vector a, Vector b) {
|
SEdge SEdge::From(Vector a, Vector b) {
|
||||||
SEdge se = { 0, a, b };
|
SEdge se = { 0, 0, 0, a, b };
|
||||||
return se;
|
return se;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,10 +61,12 @@ void SEdgeList::Clear(void) {
|
||||||
l.Clear();
|
l.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SEdgeList::AddEdge(Vector a, Vector b) {
|
void SEdgeList::AddEdge(Vector a, Vector b, int auxA, int auxB) {
|
||||||
SEdge e; ZERO(&e);
|
SEdge e; ZERO(&e);
|
||||||
e.a = a;
|
e.a = a;
|
||||||
e.b = b;
|
e.b = b;
|
||||||
|
e.auxA = auxA;
|
||||||
|
e.auxB = auxB;
|
||||||
l.Add(&e);
|
l.Add(&e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ class SBsp3;
|
||||||
class SEdge {
|
class SEdge {
|
||||||
public:
|
public:
|
||||||
int tag;
|
int tag;
|
||||||
|
int auxA, auxB;
|
||||||
Vector a, b;
|
Vector a, b;
|
||||||
|
|
||||||
static SEdge From(Vector a, Vector b);
|
static SEdge From(Vector a, Vector b);
|
||||||
|
@ -20,7 +21,7 @@ public:
|
||||||
List<SEdge> l;
|
List<SEdge> l;
|
||||||
|
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
void AddEdge(Vector a, Vector b);
|
void AddEdge(Vector a, Vector b, int auxA=0, int auxB=0);
|
||||||
bool AssemblePolygon(SPolygon *dest, SEdge *errorAt, bool keepDir=false);
|
bool AssemblePolygon(SPolygon *dest, SEdge *errorAt, bool keepDir=false);
|
||||||
bool AssembleContour(Vector first, Vector last, SContour *dest,
|
bool AssembleContour(Vector first, Vector last, SContour *dest,
|
||||||
SEdge *errorAt, bool keepDir);
|
SEdge *errorAt, bool keepDir);
|
||||||
|
|
138
srf/boolean.cpp
138
srf/boolean.cpp
|
@ -1,10 +1,144 @@
|
||||||
#include "solvespace.h"
|
#include "solvespace.h"
|
||||||
|
|
||||||
void SShell::MakeFromUnionOf(SShell *a, SShell *b) {
|
void SShell::MakeFromUnionOf(SShell *a, SShell *b) {
|
||||||
MakeFromCopyOf(b);
|
MakeFromBoolean(a, b, AS_UNION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SShell::MakeFromDifferenceOf(SShell *a, SShell *b) {
|
void SShell::MakeFromDifferenceOf(SShell *a, SShell *b) {
|
||||||
MakeFromCopyOf(b);
|
MakeFromBoolean(a, b, AS_DIFFERENCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
SCurve SCurve::MakeCopySplitAgainst(SShell *against) {
|
||||||
|
SCurve ret;
|
||||||
|
ZERO(&ret);
|
||||||
|
|
||||||
|
ret.isExact = isExact;
|
||||||
|
ret.exact = exact;
|
||||||
|
|
||||||
|
Vector *p;
|
||||||
|
for(p = pts.First(); p; p = pts.NextAfter(p)) {
|
||||||
|
ret.pts.Add(p);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SShell::CopyCurvesSplitAgainst(SShell *against, SShell *into) {
|
||||||
|
SCurve *sc;
|
||||||
|
for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) {
|
||||||
|
SCurve scn = sc->MakeCopySplitAgainst(against);
|
||||||
|
hSCurve hsc = into->curve.AddAndAssignId(&scn);
|
||||||
|
// And note the new ID so that we can rewrite the trims appropriately
|
||||||
|
sc->newH = hsc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SShell::MakeEdgeListUseNewCurveIds(SEdgeList *el) {
|
||||||
|
SEdge *se;
|
||||||
|
for(se = el->l.First(); se; se = el->l.NextAfter(se)) {
|
||||||
|
hSCurve oldh = { se->auxA };
|
||||||
|
SCurve *osc = curve.FindById(oldh);
|
||||||
|
se->auxA = osc->newH.v;
|
||||||
|
// auxB is the direction, which is unchanged
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSurface::TrimFromEdgeList(SEdgeList *el) {
|
||||||
|
el->l.ClearTags();
|
||||||
|
|
||||||
|
STrimBy stb;
|
||||||
|
ZERO(&stb);
|
||||||
|
for(;;) {
|
||||||
|
// Find an edge, any edge; we'll start from there.
|
||||||
|
SEdge *se;
|
||||||
|
for(se = el->l.First(); se; se = el->l.NextAfter(se)) {
|
||||||
|
if(se->tag) continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!se) break;
|
||||||
|
se->tag = 1;
|
||||||
|
stb.start = se->a;
|
||||||
|
stb.finish = se->b;
|
||||||
|
stb.curve.v = se->auxA;
|
||||||
|
stb.backwards = se->auxB ? true : false;
|
||||||
|
|
||||||
|
// Find adjoining edges from the same curve; those should be
|
||||||
|
// merged into a single trim.
|
||||||
|
bool merged;
|
||||||
|
do {
|
||||||
|
merged = false;
|
||||||
|
for(se = el->l.First(); se; se = el->l.NextAfter(se)) {
|
||||||
|
if(se->tag) continue;
|
||||||
|
if(se->auxA != stb.curve.v) continue;
|
||||||
|
if(( se->auxB && !stb.backwards) ||
|
||||||
|
(!se->auxB && stb.backwards)) continue;
|
||||||
|
|
||||||
|
if((se->a).Equals(stb.finish)) {
|
||||||
|
stb.finish = se->b;
|
||||||
|
se->tag = 1;
|
||||||
|
merged = true;
|
||||||
|
} else if((se->b).Equals(stb.start)) {
|
||||||
|
stb.start = se->a;
|
||||||
|
se->tag = 1;
|
||||||
|
merged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(merged);
|
||||||
|
|
||||||
|
// And add the merged trim, with xyz (not uv like the polygon) pts
|
||||||
|
stb.start = PointAt(stb.start.x, stb.start.y);
|
||||||
|
stb.finish = PointAt(stb.finish.x, stb.finish.y);
|
||||||
|
trim.Add(&stb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Trim this surface against the specified shell, in the way that's appropriate
|
||||||
|
// for the specified Boolean operation type (and which operand we are). We
|
||||||
|
// also need a pointer to the shell that contains our own surface, since that
|
||||||
|
// contains our original trim curves.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
SSurface SSurface::MakeCopyTrimAgainst(SShell *against, SShell *shell,
|
||||||
|
int type, bool opA)
|
||||||
|
{
|
||||||
|
SSurface ret;
|
||||||
|
// The returned surface is identical, just the trim curves change
|
||||||
|
ret = *this;
|
||||||
|
ZERO(&(ret.trim));
|
||||||
|
|
||||||
|
SEdgeList el;
|
||||||
|
ZERO(&el);
|
||||||
|
MakeEdgesInto(shell, &el, true);
|
||||||
|
shell->MakeEdgeListUseNewCurveIds(&el);
|
||||||
|
|
||||||
|
ret.TrimFromEdgeList(&el);
|
||||||
|
|
||||||
|
el.Clear();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SShell::CopySurfacesTrimAgainst(SShell *against, SShell *into,
|
||||||
|
int type, bool opA)
|
||||||
|
{
|
||||||
|
SSurface *ss;
|
||||||
|
for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
|
||||||
|
SSurface ssn;
|
||||||
|
ssn = ss->MakeCopyTrimAgainst(against, this, type, opA);
|
||||||
|
into->surface.AddAndAssignId(&ssn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SShell::MakeFromBoolean(SShell *a, SShell *b, int type) {
|
||||||
|
// Copy over all the original curves, splitting them so that a
|
||||||
|
// piecwise linear segment never crosses a surface from the other
|
||||||
|
// shell.
|
||||||
|
a->CopyCurvesSplitAgainst(b, this);
|
||||||
|
b->CopyCurvesSplitAgainst(a, this);
|
||||||
|
|
||||||
|
// Generate the intersection curves for each surface in A against all
|
||||||
|
// the surfaces in B
|
||||||
|
|
||||||
|
// Then trim and copy the surfaces
|
||||||
|
a->CopySurfacesTrimAgainst(b, this, type, true);
|
||||||
|
b->CopySurfacesTrimAgainst(a, this, type, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,17 @@ void SBezier::Reverse(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SBezier::GetBoundingProjd(Vector u, Vector orig,
|
||||||
|
double *umin, double *umax)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i <= deg; i++) {
|
||||||
|
double ut = ((ctrl[i]).Minus(orig)).Dot(u);
|
||||||
|
if(ut < *umin) *umin = ut;
|
||||||
|
if(ut > *umax) *umax = ut;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SBezier SBezier::TransformedBy(Vector t, Quaternion q) {
|
SBezier SBezier::TransformedBy(Vector t, Quaternion q) {
|
||||||
SBezier ret = *this;
|
SBezier ret = *this;
|
||||||
int i;
|
int i;
|
||||||
|
@ -228,6 +239,15 @@ void SBezierLoop::Reverse(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SBezierLoop::GetBoundingProjd(Vector u, Vector orig,
|
||||||
|
double *umin, double *umax)
|
||||||
|
{
|
||||||
|
SBezier *sb;
|
||||||
|
for(sb = l.First(); sb; sb = l.NextAfter(sb)) {
|
||||||
|
sb->GetBoundingProjd(u, orig, umin, umax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SBezierLoop::MakePwlInto(SContour *sc) {
|
void SBezierLoop::MakePwlInto(SContour *sc) {
|
||||||
List<Vector> lv;
|
List<Vector> lv;
|
||||||
ZERO(&lv);
|
ZERO(&lv);
|
||||||
|
@ -292,6 +312,15 @@ SBezierLoopSet SBezierLoopSet::From(SBezierList *sbl, SPolygon *poly,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SBezierLoopSet::GetBoundingProjd(Vector u, Vector orig,
|
||||||
|
double *umin, double *umax)
|
||||||
|
{
|
||||||
|
SBezierLoop *sbl;
|
||||||
|
for(sbl = l.First(); sbl; sbl = l.NextAfter(sbl)) {
|
||||||
|
sbl->GetBoundingProjd(u, orig, umin, umax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SBezierLoopSet::Clear(void) {
|
void SBezierLoopSet::Clear(void) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
|
@ -358,15 +387,13 @@ SSurface SSurface::FromExtrusionOf(SBezier *sb, Vector t0, Vector t1) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSurface SSurface::FromPlane(Vector pt, Vector n) {
|
SSurface SSurface::FromPlane(Vector pt, Vector u, Vector v) {
|
||||||
SSurface ret;
|
SSurface ret;
|
||||||
ZERO(&ret);
|
ZERO(&ret);
|
||||||
|
|
||||||
ret.degm = 1;
|
ret.degm = 1;
|
||||||
ret.degn = 1;
|
ret.degn = 1;
|
||||||
|
|
||||||
Vector u = n.Normal(0), v = n.Normal(1);
|
|
||||||
|
|
||||||
ret.weight[0][0] = ret.weight[0][1] = 1;
|
ret.weight[0][0] = ret.weight[0][1] = 1;
|
||||||
ret.weight[1][0] = ret.weight[1][1] = 1;
|
ret.weight[1][0] = ret.weight[1][1] = 1;
|
||||||
|
|
||||||
|
@ -520,7 +547,7 @@ void SSurface::MakeEdgesInto(SShell *shell, SEdgeList *sel, bool asUv) {
|
||||||
SCurve *sc = shell->curve.FindById(stb->curve);
|
SCurve *sc = shell->curve.FindById(stb->curve);
|
||||||
|
|
||||||
Vector prev, prevuv, ptuv;
|
Vector prev, prevuv, ptuv;
|
||||||
bool inCurve = false;
|
bool inCurve = false, empty = true;
|
||||||
double u = 0, v = 0;
|
double u = 0, v = 0;
|
||||||
|
|
||||||
int i, first, last, increment;
|
int i, first, last, increment;
|
||||||
|
@ -539,18 +566,23 @@ void SSurface::MakeEdgesInto(SShell *shell, SEdgeList *sel, bool asUv) {
|
||||||
ClosestPointTo(*pt, &u, &v);
|
ClosestPointTo(*pt, &u, &v);
|
||||||
ptuv = Vector::From(u, v, 0);
|
ptuv = Vector::From(u, v, 0);
|
||||||
if(inCurve) {
|
if(inCurve) {
|
||||||
sel->AddEdge(prevuv, ptuv);
|
sel->AddEdge(prevuv, ptuv, sc->h.v, stb->backwards);
|
||||||
|
empty = false;
|
||||||
}
|
}
|
||||||
prevuv = ptuv;
|
prevuv = ptuv;
|
||||||
} else {
|
} else {
|
||||||
if(inCurve) {
|
if(inCurve) {
|
||||||
sel->AddEdge(prev, *pt);
|
sel->AddEdge(prev, *pt, sc->h.v, stb->backwards);
|
||||||
|
empty = false;
|
||||||
}
|
}
|
||||||
prev = *pt;
|
prev = *pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pt->EqualsExactly(stb->start)) inCurve = true;
|
if(pt->Equals(stb->start)) inCurve = true;
|
||||||
if(pt->EqualsExactly(stb->finish)) inCurve = false;
|
if(pt->Equals(stb->finish)) inCurve = false;
|
||||||
|
}
|
||||||
|
if(inCurve || empty) {
|
||||||
|
dbp("trim was empty or unterminated");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -604,12 +636,27 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
|
||||||
SWAP(Vector, t0, t1);
|
SWAP(Vector, t0, t1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, generate the top and bottom surfaces of the extrusion; just
|
// Define a coordinate system to contain the original sketch, and get
|
||||||
// planes.
|
// a bounding box in that csys
|
||||||
|
Vector n = sbls->normal.ScaledBy(-1);
|
||||||
|
Vector u = n.Normal(0), v = n.Normal(1);
|
||||||
|
Vector orig = sbls->point;
|
||||||
|
double umax = 1e-10, umin = 1e10;
|
||||||
|
sbls->GetBoundingProjd(u, orig, &umin, &umax);
|
||||||
|
double vmax = 1e-10, vmin = 1e10;
|
||||||
|
sbls->GetBoundingProjd(v, orig, &vmin, &vmax);
|
||||||
|
// and now fix things up so that all u and v lie between 0 and 1
|
||||||
|
orig = orig.Plus(u.ScaledBy(umin));
|
||||||
|
orig = orig.Plus(v.ScaledBy(vmin));
|
||||||
|
u = u.ScaledBy(umax - umin);
|
||||||
|
v = v.ScaledBy(vmax - vmin);
|
||||||
|
|
||||||
|
// So we can now generate the top and bottom surfaces of the extrusion,
|
||||||
|
// planes within a translated (and maybe mirrored) version of that csys.
|
||||||
SSurface s0, s1;
|
SSurface s0, s1;
|
||||||
s0 = SSurface::FromPlane(sbls->point.Plus(t0), sbls->normal.ScaledBy(-1));
|
s0 = SSurface::FromPlane(orig.Plus(t0), u, v);
|
||||||
s0.color = color;
|
s0.color = color;
|
||||||
s1 = SSurface::FromPlane(sbls->point.Plus(t1), sbls->normal.ScaledBy( 1));
|
s1 = SSurface::FromPlane(orig.Plus(t1).Plus(u), u.ScaledBy(-1), v);
|
||||||
s1.color = color;
|
s1.color = color;
|
||||||
hSSurface hs0 = surface.AddAndAssignId(&s0),
|
hSSurface hs0 = surface.AddAndAssignId(&s0),
|
||||||
hs1 = surface.AddAndAssignId(&s1);
|
hs1 = surface.AddAndAssignId(&s1);
|
||||||
|
|
|
@ -34,6 +34,7 @@ public:
|
||||||
void MakePwlInto(List<Vector> *l, Vector offset);
|
void MakePwlInto(List<Vector> *l, Vector offset);
|
||||||
void MakePwlWorker(List<Vector> *l, double ta, double tb, Vector offset);
|
void MakePwlWorker(List<Vector> *l, double ta, double tb, Vector offset);
|
||||||
|
|
||||||
|
void GetBoundingProjd(Vector u, Vector orig, double *umin, double *umax);
|
||||||
void Reverse(void);
|
void Reverse(void);
|
||||||
|
|
||||||
SBezier TransformedBy(Vector t, Quaternion q);
|
SBezier TransformedBy(Vector t, Quaternion q);
|
||||||
|
@ -57,6 +58,7 @@ public:
|
||||||
inline void Clear(void) { l.Clear(); }
|
inline void Clear(void) { l.Clear(); }
|
||||||
void Reverse(void);
|
void Reverse(void);
|
||||||
void MakePwlInto(SContour *sc);
|
void MakePwlInto(SContour *sc);
|
||||||
|
void GetBoundingProjd(Vector u, Vector orig, double *umin, double *umax);
|
||||||
|
|
||||||
static SBezierLoop FromCurves(SBezierList *spcl,
|
static SBezierLoop FromCurves(SBezierList *spcl,
|
||||||
bool *allClosed, SEdge *errorAt);
|
bool *allClosed, SEdge *errorAt);
|
||||||
|
@ -71,6 +73,7 @@ public:
|
||||||
static SBezierLoopSet From(SBezierList *spcl, SPolygon *poly,
|
static SBezierLoopSet From(SBezierList *spcl, SPolygon *poly,
|
||||||
bool *allClosed, SEdge *errorAt);
|
bool *allClosed, SEdge *errorAt);
|
||||||
|
|
||||||
|
void GetBoundingProjd(Vector u, Vector orig, double *umin, double *umax);
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,13 +82,15 @@ class SCurve {
|
||||||
public:
|
public:
|
||||||
hSCurve h;
|
hSCurve h;
|
||||||
|
|
||||||
|
hSCurve newH; // when merging with booleans
|
||||||
|
|
||||||
bool isExact;
|
bool isExact;
|
||||||
SBezier exact;
|
SBezier exact;
|
||||||
|
|
||||||
List<Vector> pts;
|
List<Vector> pts;
|
||||||
|
|
||||||
static SCurve SCurve::FromTransformationOf(SCurve *a,
|
static SCurve FromTransformationOf(SCurve *a, Vector t, Quaternion q);
|
||||||
Vector t, Quaternion q);
|
SCurve MakeCopySplitAgainst(SShell *against);
|
||||||
|
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
};
|
};
|
||||||
|
@ -122,10 +127,14 @@ public:
|
||||||
List<STrimBy> trim;
|
List<STrimBy> trim;
|
||||||
|
|
||||||
static SSurface FromExtrusionOf(SBezier *spc, Vector t0, Vector t1);
|
static SSurface FromExtrusionOf(SBezier *spc, Vector t0, Vector t1);
|
||||||
static SSurface FromPlane(Vector pt, Vector n);
|
static SSurface FromPlane(Vector pt, Vector u, Vector v);
|
||||||
static SSurface FromTransformationOf(SSurface *a, Vector t, Quaternion q,
|
static SSurface FromTransformationOf(SSurface *a, Vector t, Quaternion q,
|
||||||
bool includingTrims);
|
bool includingTrims);
|
||||||
|
|
||||||
|
SSurface MakeCopyTrimAgainst(SShell *against, SShell *shell,
|
||||||
|
int type, bool opA);
|
||||||
|
void TrimFromEdgeList(SEdgeList *el);
|
||||||
|
|
||||||
void ClosestPointTo(Vector p, double *u, double *v);
|
void ClosestPointTo(Vector p, double *u, double *v);
|
||||||
Vector PointAt(double u, double v);
|
Vector PointAt(double u, double v);
|
||||||
void TangentsAt(double u, double v, Vector *tu, Vector *tv);
|
void TangentsAt(double u, double v, Vector *tu, Vector *tv);
|
||||||
|
@ -144,8 +153,17 @@ public:
|
||||||
|
|
||||||
void MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
|
void MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1,
|
||||||
int color);
|
int color);
|
||||||
|
|
||||||
void MakeFromUnionOf(SShell *a, SShell *b);
|
void MakeFromUnionOf(SShell *a, SShell *b);
|
||||||
void MakeFromDifferenceOf(SShell *a, SShell *b);
|
void MakeFromDifferenceOf(SShell *a, SShell *b);
|
||||||
|
static const int AS_UNION = 10;
|
||||||
|
static const int AS_DIFFERENCE = 11;
|
||||||
|
static const int AS_INTERSECT = 12;
|
||||||
|
void MakeFromBoolean(SShell *a, SShell *b, int type);
|
||||||
|
void CopyCurvesSplitAgainst(SShell *against, SShell *into);
|
||||||
|
void CopySurfacesTrimAgainst(SShell *against, SShell *into, int t, bool a);
|
||||||
|
void MakeEdgeListUseNewCurveIds(SEdgeList *el);
|
||||||
|
|
||||||
void MakeFromCopyOf(SShell *a);
|
void MakeFromCopyOf(SShell *a);
|
||||||
void MakeFromTransformationOf(SShell *a, Vector trans, Quaternion q);
|
void MakeFromTransformationOf(SShell *a, Vector trans, Quaternion q);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user