[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gzz-commits] libvob include/vob/Vec23.hxx include/vob/geom/F...
From: |
Tuomas J. Lukka |
Subject: |
[Gzz-commits] libvob include/vob/Vec23.hxx include/vob/geom/F... |
Date: |
Mon, 02 Jun 2003 14:18:42 -0400 |
CVSROOT: /cvsroot/libvob
Module name: libvob
Changes by: Tuomas J. Lukka <address@hidden> 03/06/02 14:18:42
Modified files:
include/vob : Vec23.hxx
include/vob/geom: Fillets2.hxx Quadrics.hxx
include/vob/vobs: Fillet.hxx
vob/demo/multifil: multifil.py
Log message:
Fillets clearer implementation
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/include/vob/Vec23.hxx.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/include/vob/geom/Fillets2.hxx.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/include/vob/geom/Quadrics.hxx.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/include/vob/vobs/Fillet.hxx.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/libvob/libvob/vob/demo/multifil/multifil.py.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
Patches:
Index: libvob/include/vob/Vec23.hxx
diff -u libvob/include/vob/Vec23.hxx:1.8 libvob/include/vob/Vec23.hxx:1.9
--- libvob/include/vob/Vec23.hxx:1.8 Thu May 29 04:00:20 2003
+++ libvob/include/vob/Vec23.hxx Mon Jun 2 14:18:41 2003
@@ -104,7 +104,7 @@
/** Cross this 2D vector with another -
* gives the sine of the angle between the two,
* multiplied by the lengths.
- * Useful for telling which side of a given vector you are.
+ * Useful for telling which side of a given vector you are on.
*/
double cross(const Vector<T> &v) const {
return x * v.y - y * v.x;
Index: libvob/include/vob/geom/Fillets2.hxx
diff -u libvob/include/vob/geom/Fillets2.hxx:1.1
libvob/include/vob/geom/Fillets2.hxx:1.2
--- libvob/include/vob/geom/Fillets2.hxx:1.1 Sun Jun 1 07:49:15 2003
+++ libvob/include/vob/geom/Fillets2.hxx Mon Jun 2 14:18:41 2003
@@ -14,7 +14,21 @@
struct FilletSpanConcept {
/** Get the point on this part of the edge.
*/
- ZVec point(float fract, ZVec *intern = 0) {
+ ZVec point(float fract, ZVec *intern = 0) const {
+ return ZVec(0,0,0);
+ }
+ };
+
+ /** Concept: a blendable span of edge.
+ * Usually, the 0-side is the connection and 1 is
+ * return to circle (or other point).
+ */
+ struct BlendableFilletSpanConcept : public FilletSpanConcept{
+ /** Get the point on a given direction vector.
+ * @param dir The unit direction vector from the center.
+ * @param success Boolean into which to return whether there was
something.
+ */
+ ZVec point(Vec dir, bool *success) {
return ZVec(0,0,0);
}
};
@@ -22,18 +36,218 @@
/** A circular node.
*/
struct CircularNode {
+ /** The center of the node.
+ */
ZVec ctr;
+ /** The radius of the node.
+ */
float r;
+
+ CircularNode(ZVec ctr, float r) : ctr(ctr), r(r) { }
+
+ ZVec point(Vec dir) {
+ return ctr + r * dir;
+ }
};
- /** A connection
+ /** A connection. The node is assumed to be known.
+ */
+ struct LinearConnectionHalf {
+ const CircularNode &node;
+
+ /** The compass angle of the connection.
+ */
+ float a;
+ /** The distance from the center to the middle of the connection.
+ */
+ float d;
+ /** The thickness of the connection at the middle.
+ */
+ float t;
+ /** Whether we're looking at the clockwise or counterclockwise side.
+ */
+ int sign;
+ /** The z coordinate of the middle.
+ */
+ float z;
+
+ /////////////////////////////////
+ // The following data members are derivable from the already mentioned
ones.
+ // They are calculated here to be cached.
+
+ /** The direction (unit) vector.
+ */
+ Vec dir;
+
+ /** The normal (unit) vector.
+ */
+ Vec norm;
+
+ /** The endpoint of the edge.
+ */
+ ZVec endPoint;
+
+ LinearConnectionHalf(
+ const CircularNode &node,
+ float a,
+ float d,
+ float t,
+ int sign,
+ float z) :
+ node(node),
+ a(a),
+ d(d),
+ t(t),
+ sign(sign),
+ z(z) {
+ dir = dirVec(a);
+ norm = dir.cw90() * sign;
+ endPoint = node.ctr + d * dir + t/2 * norm;
+ }
+
+ /** Project a given point to the connecting line.
+ * If the point would go to the negative direction (or inside the
circular
+ * node) on the connection
+ * line, it will be clamped to the center.
+ * Useful for generating internal points.
+ */
+ ZVec projectToConnLine(ZVec v) const {
+ v = v - norm.dot(v-node.ctr) * norm;
+ if(dir.dot(v-node.ctr) <= node.r) {
+ v = v - dir.dot(v-node.ctr) * dir;
+ }
+ v.z = lerp(node.ctr.z, z, (dir.dot(v-node.ctr) - node.r) / (d -
node.r));
+ return v;
+ }
+
+ };
/** A circular fillet edge span, for a circular node.
*/
struct CircleCircleFillet {
+ const CircularNode &node;
+ const LinearConnectionHalf &conn;
+
+ Vec fcenter;
+ float frad;
+
+ /** The direction vector from the center of the node
+ * to the point where
+ * the two circles are tangent.
+ */
+ Vec dirtang;
+
+ float dtsign;
+
+ float astart;
+ float aend;
+
CircleCircleFillet(
- CircularNode &n,
+ const CircularNode &node,
+ const LinearConnectionHalf &conn) : node(node), conn(conn) {
+ this->fcenter =
+ circle__point_norm_circle(conn.endPoint, conn.norm, node.ctr,
node.r);
+ this->frad =
+ (fcenter - conn.endPoint).length();
+ this->dirtang = (fcenter - node.ctr) . normalized();
+ this->dtsign = dirtang.cross(conn.dir);
+ this->astart = Vec(conn.endPoint - fcenter).atan();
+ this->aend = Vec(node.ctr - fcenter).atan();
+ while(aend - astart >= M_PI) aend -= 2 * M_PI;
+ while(astart - aend >= M_PI) aend += 2 * M_PI;
+ }
+
+ /** For blending, we want to stop the fillet halfway to avoid
+ * overdraw and strange shapes while cleaving.
+ */
+ void cutEnd(Vec dir) {
+ bool success;
+ ZVec in = project2circle(node.ctr + dir, node.ctr, fcenter,
+ frad, -1, &success);
+ if(success) return;
+ this->aend = Vec(in-fcenter).atan();
+ while(aend - astart >= M_PI) aend -= 2 * M_PI;
+ while(astart - aend >= M_PI) aend += 2 * M_PI;
+ }
+
+ ZVec point(float fract, ZVec *intern = 0) const {
+ ZVec pt = fcenter + frad * dirVec(lerp(astart, aend, fract));
+ ZVec proj = conn.projectToConnLine(pt);
+ pt.z = proj.z;
+ if(intern) *intern = proj;
+ return pt;
+ }
+
+ ZVec point(Vec dir, bool &success) const {
+ if(dirtang.cross(dir) * dtsign < 0) {
+ success = false;
+ return ZVec(0,0,0);
+ }
+ ZVec in = project2circle(node.ctr + dir, node.ctr, fcenter,
+ frad, -1, &success);
+ if(!success) return ZVec(0,0,0);
+ ZVec proj = conn.projectToConnLine(in);
+ in.z = proj.z;
+ return in;
+ }
+
+ bool infillet(Vec dir) const {
+ return dirtang.cross(conn.dir) * dirtang.cross(dir) >= 0 &&
+ conn.dir.cross(dirtang) * conn.dir.cross(dir) >= 0;
+ }
+ bool overlaps(const CircleCircleFillet &other) const {
+ return infillet(other.dirtang) || other.infillet(dirtang);
+ }
};
+
+ /** A blend of two fillets.
+ * Note that this is only one side of the blend!
+ */
+ struct FilletBlend {
+ CircleCircleFillet main;
+ const CircleCircleFillet &other;
+
+ FilletBlend(const CircleCircleFillet &main0,
+ const CircleCircleFillet &other) :
+ main(main0), other(other) {
+ Vec cutdir = (main.dirtang + other.dirtang).normalized();
+ main.cutEnd(cutdir);
+ }
+
+ ZVec point(float fract, ZVec *intern = 0) const {
+ ZVec p = main.point(fract, intern);
+ bool success;
+ ZVec p2 = other.point(Vec(p-main.node.ctr).normalized(), success);
+ ZVec res;
+ if(success) {
+ ZVec edgep = .5 *(p + p2 - 2 * main.node.ctr);
+ edgep *= main.node.r / edgep.xylength();
+ edgep += main.node.ctr;
+ res = p + p2 - edgep;
+ } else {
+ res = p;
+ }
+ return res;
+ }
+ };
+
+
+ struct CircularNodeSpan {
+ const CircularNode &node;
+ float astart;
+ float aend;
+ CircularNodeSpan(const CircularNode &node,
+ float astart, float aend) :
+ node(node), astart(astart), aend(aend) {
+ }
+
+ ZVec point(float fract, ZVec *intern = 0) const {
+ if(intern) *intern = node.ctr;
+ return node.ctr + node.r * dirVec(lerp(astart, aend, fract));
+ }
+
+ };
+
}
}
Index: libvob/include/vob/geom/Quadrics.hxx
diff -u libvob/include/vob/geom/Quadrics.hxx:1.3
libvob/include/vob/geom/Quadrics.hxx:1.4
--- libvob/include/vob/geom/Quadrics.hxx:1.3 Thu May 29 04:00:20 2003
+++ libvob/include/vob/geom/Quadrics.hxx Mon Jun 2 14:18:42 2003
@@ -1,5 +1,8 @@
// (c) Tuomas J. Lukka
+#ifndef VOB_GEOM_QUADRICS
+#define VOB_GEOM_QUADRICS
+
#include <vob/Vec23.hxx>
namespace Vob {
@@ -67,3 +70,6 @@
}
}
+
+
+#endif
Index: libvob/include/vob/vobs/Fillet.hxx
diff -u libvob/include/vob/vobs/Fillet.hxx:1.5
libvob/include/vob/vobs/Fillet.hxx:1.6
--- libvob/include/vob/vobs/Fillet.hxx:1.5 Fri May 30 10:47:09 2003
+++ libvob/include/vob/vobs/Fillet.hxx Mon Jun 2 14:18:42 2003
@@ -40,6 +40,7 @@
#include <vob/glerr.hxx>
#include <vob/geom/Fillets.hxx>
+#include <vob/geom/Fillets2.hxx>
#ifndef VOB_DEFINED
#define VOB_DEFINED(t)
@@ -174,8 +175,6 @@
FilletSpan sp(ctr, csize,
a1, d1, th1, lerp(p0.z, p1.z, .5),
a2, d2, th2, lerp(p0.z, p2.z, .5));
- // Render it. XXX -- jvk, you need to make this
- // render the solid fillet.
if(!(flags & 8)) {
if(sp.split()) {
if(flags & 1) {
@@ -257,7 +256,135 @@
}
};
+
VOB_DEFINED(FilletSpan1);
+
+struct FilletSpan2 {
+ enum { NTrans = 3 };
+
+ int ndice;
+ int flags;
+
+ template<class T> float crad(const T &t) const {
+ return t.getSqSize().x;
+ }
+ template<class T> float th(const T &t0, const T &t1, float d) const {
+ float r0 = crad(t0);
+ float r1 = crad(t1);
+ float rmax = r0 >? r1;
+ float rmin = r0 <? r1;
+ if(d <= rmax - rmin) return .96 * rmin;
+ float dr = (d - (rmax-rmin)) / (r0 + r1);
+ return .96 * rmin * 1 / (1 + dr);
+ }
+
+ template<class F> void params(F &f) {
+ f(ndice, flags);
+ }
+
+ void v(ZVec p) const {
+ if(flags & 4) {
+ glColor3f(1, p.z / 100, p.z / 100);
+ }
+ glVertex(p);
+ }
+
+ void vl(ZVec p) const {
+ if(flags & 4) {
+ glColor3f(0,p.z / 100, p.z / 100);
+ }
+ glVertex(p);
+ }
+
+ template<class G> void renderSpanSolid(const G &g) const {
+ glBegin(GL_QUAD_STRIP);
+ for(int i=0; i<ndice; i++) {
+ float fract = i / (ndice-1.0);
+ ZVec intern;
+ ZVec pt = g.point(fract, &intern);
+ v(pt);
+ v(intern);
+ }
+ glEnd();
+ }
+
+ template<class G> void renderSpanLine(const G &g) const {
+ glBegin(GL_LINE_STRIP);
+ for(int i=0; i<ndice; i++) {
+ float fract = i / (ndice-1.0);
+ ZVec pt = g.point(fract, 0);
+ vl(pt);
+ }
+ glEnd();
+ }
+
+ template<class G> void renderSpan(const G &g) const {
+ if(flags & 1)
+ renderSpanSolid(g);
+ if(flags & 2)
+ renderSpanLine(g);
+ }
+
+
+
+ template<class T> void render(const T &t0, const T &t1, const T &t2)
+ const {
+ ZVec p0 = t0.transform(t0.getSqSize());
+ ZVec p1 = t1.transform(t1.getSqSize()) ;
+ ZVec p2 = t2.transform(t2.getSqSize()) ;
+
+ ZVec ctr = p0;
+ Vec v1 = p1 - ctr;
+ Vec v2 = p2 - ctr;
+
+ DBG(dbg_vfillets) << "FilletSpan "<<ctr<<" "<<v1<<" "<<v2<<"\n";
+
+ float a1 = v1.atan();
+ float a2 = v2.atan();
+ if(a2 < a1 || &t1 == &t2) a2 += 2*M_PI;
+
+ float d1 = v1.length() / 2;
+ float d2 = v2.length() / 2;
+
+ float th1 = th(t0, t1, d1);
+ float th2 = th(t0, t2, d2);
+
+ float csize = crad(t0);
+
+ DBG(dbg_vfillets) << "P: "<<ctr<<" "<<csize<<" "<<
+ a1<<" "<<d1<<" "<<th1<<" "<<
+ a2<<" "<<d2<<" "<<th2<<" "<<
+ "\n";
+
+ CircularNode node(ctr, csize);
+ LinearConnectionHalf c1(node, a1, d1, th1, 1, lerp(p0.z, p1.z, .5));
+ LinearConnectionHalf c2(node, a2, d2, th2, -1, lerp(p0.z, p2.z, .5));
+
+ CircleCircleFillet f1(node, c1);
+ CircleCircleFillet f2(node, c2);
+
+ // Find out how close they are.
+/* if(a2-a1 < M_PI &&
+ (f1.containsConnection(f2) ||
+ f2.containsConnection(f1))) {
+ // Cleaved case
+ } else */ if(f1.overlaps(f2)) {
+ renderSpan(FilletBlend(f1, f2));
+ renderSpan(FilletBlend(f2, f1));
+ } else {
+ renderSpan(f1);
+ float ta1 = f1.dirtang.atan();
+ float ta2 = f2.dirtang.atan();
+ if(ta2 < ta1) ta2 += 2*M_PI;
+ renderSpan(CircularNodeSpan(node, ta1, ta2));
+ renderSpan(f2);
+ }
+
+ }
+
+
+};
+VOB_DEFINED(FilletSpan2);
}
}
Index: libvob/vob/demo/multifil/multifil.py
diff -u libvob/vob/demo/multifil/multifil.py:1.3
libvob/vob/demo/multifil/multifil.py:1.4
--- libvob/vob/demo/multifil/multifil.py:1.3 Fri May 30 10:47:09 2003
+++ libvob/vob/demo/multifil/multifil.py Mon Jun 2 14:18:42 2003
@@ -39,9 +39,9 @@
dice = 200
conns = GLRen.createSortedConnections(
- GLRen.createFilletSpan1(dice, 1 + 4*self.depthColor +
8*(1-self.fillets)))
+ GLRen.createFilletSpan2(dice, 1 + 4*self.depthColor +
8*(1-self.fillets)))
conns_l = GLRen.createSortedConnections(
- GLRen.createFilletSpan1(dice, 2 + 4*self.depthColor +
8*(1-self.fillets)))
+ GLRen.createFilletSpan2(dice, 2 + 4*self.depthColor +
8*(1-self.fillets)))
size = 50
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gzz-commits] libvob include/vob/Vec23.hxx include/vob/geom/F...,
Tuomas J. Lukka <=