[Bf-blender-cvs] [a1fd376] soc-2014-nurbs: Added support for drawing, moving, and inserting vertices in multiple subject polygons
Jonathan deWerd
noreply at git.blender.org
Fri Jun 27 08:14:30 CEST 2014
Commit: a1fd3764fa08fac1040ce6f6e5a6e15a78472440
Author: Jonathan deWerd
Date: Sun Jun 15 22:29:23 2014 -0400
https://developer.blender.org/rBa1fd3764fa08fac1040ce6f6e5a6e15a78472440
Added support for drawing, moving, and inserting vertices in multiple subject polygons
===================================================================
M PolyTest/poly.cpp
M PolyTest/poly_demo.cpp
===================================================================
diff --git a/PolyTest/poly.cpp b/PolyTest/poly.cpp
index 167c25d..a0251c6 100644
--- a/PolyTest/poly.cpp
+++ b/PolyTest/poly.cpp
@@ -6,9 +6,12 @@ struct GreinerV2f {
struct GreinerV2f *nextPoly; // First vertex of the *next* polygon
bool isIntersection; // True if this vertex was added at an intersection
bool isEntry; // True if proceeding along this poly with ->next->next will enter the other polygon when this vertex is passed
+ bool isBackbone;
struct GreinerV2f *neighbour; // Corresp. vertex at same {x,y} in different polygon
float alpha; // If this vertex came from an affine comb, this is the mixing factor
- GreinerV2f() : next(nullptr), prev(nullptr), nextPoly(nullptr), neighbour(nullptr), isIntersection(false) {};
+ GreinerV2f() : next(nullptr), prev(nullptr),
+ nextPoly(nullptr), neighbour(nullptr),
+ isIntersection(false), isBackbone(false) {};
};
GreinerV2f* insert_vert_at_intersect(GreinerV2f* poly1left,
diff --git a/PolyTest/poly_demo.cpp b/PolyTest/poly_demo.cpp
index 89c6eb8..c17cf4b 100644
--- a/PolyTest/poly_demo.cpp
+++ b/PolyTest/poly_demo.cpp
@@ -27,20 +27,18 @@ float intersect_check_tol = .001; //Maximum Euclidean dist between intersect pts
#include "poly.cpp"
/***************************** DEFAULT SCENE *****************************/
-//int clip_n = 2;
-//float clip_verts[] = {0,0, 0.5,0.5};
-//int subj_n = 2;
-//float subj_verts[] = {-.5,-.5, .5,-.5};
bool clip_cyclic = true; // Required for initialization
-bool subj_cyclic = true;
std::vector<float> clip_verts = {-0.460000,-0.004000, 0.360000,-0.072000, 0.388000,-0.744000, -0.440000,-0.720000};
-std::vector<float> subj_verts = {-0.500000,-0.500000, 0.500000,-0.500000};
-std::vector<float> inout_pts = {};
+bool subj_cyclic = true;
+std::vector<float> subj0 = {-0.500000,-0.500000, 0.500000,-0.500000};
+std::vector<float> subj1 = {-0.500000,-0.000000, 0.500000,-0.000000};
+std::vector<std::vector<float>> subj_polys = {subj0,subj1};
+std::vector<float> inout_pts;
-GreinerV2f *clip;
-GreinerV2f *subj;
+GreinerV2f *clip = nullptr;
+GreinerV2f *subj = nullptr; // Uses the linked list param nextPoly!
int win_width = 500;
int win_height = 500;
@@ -53,9 +51,9 @@ void glut_coords_2_scene(float gx, float gy, float* sx, float* sy) {
}
void init_default_scene() {
+ // Import the clip polygon into the linked-list datastructure
GreinerV2f *last = nullptr;
size_t clip_n = clip_verts.size()/2;
- size_t subj_n = subj_verts.size()/2;
for (int i=0; i<clip_n; i++) {
GreinerV2f *v = new GreinerV2f();
v->x = clip_verts[2*i+0];
@@ -69,19 +67,40 @@ void init_default_scene() {
clip->prev = last;
last->next = clip;
}
+ clip->isBackbone = true;
+ // Import the subject polygons into the linked list datastructure
last = nullptr;
- for (int i=0; i<subj_n; i++) {
- GreinerV2f *v = new GreinerV2f();
- v->x = subj_verts[2*i+0];
- v->y = subj_verts[2*i+1];
- v->prev = last;
- if (last) last->next = v;
- else subj = v;
- last = v;
- }
- if (subj_cyclic) {
- subj->prev = last;
- last->next = subj;
+ for (std::vector<float> poly_verts : subj_polys) {
+ // Different subject polygons are stored in
+ // subj, subj->nextPoly, subj->nextPoly->nextPoly etc
+ GreinerV2f *newpoly_first_vert = new GreinerV2f();
+ newpoly_first_vert -> isBackbone = true;
+ if (!subj) {
+ subj = newpoly_first_vert;
+ } else {
+ last->nextPoly = newpoly_first_vert;
+ }
+ last = newpoly_first_vert;
+ // Fill in the vertices of the polygon we just finished hooking up
+ // to the polygon list
+ GreinerV2f *last_inner = nullptr;
+ for (size_t i=0,l=poly_verts.size()/2; i<l; i++) {
+ GreinerV2f *v;
+ if (i==0) {
+ v = newpoly_first_vert;
+ } else {
+ v = new GreinerV2f();
+ }
+ v->x = poly_verts[2*i+0];
+ v->y = poly_verts[2*i+1];
+ v->prev = last_inner;
+ if (last_inner) last_inner->next = v;
+ last_inner = v;
+ }
+ if (subj_cyclic) {
+ newpoly_first_vert->prev = last_inner;
+ last_inner->next = newpoly_first_vert;
+ }
}
}
@@ -131,30 +150,38 @@ void GLUT_display(){
// Draw Subject polygon lines
glBegin(GL_LINES);
- is_outside = true;
- last_x=subj->x, last_y=subj->y;
- if (clip_cyclic) is_outside = point_in_polygon(last_x, last_y, subj);
- for (GreinerV2f *v=subj->next; v; v=v->next) {
- float x=v->x, y=v->y;
- if (is_outside) glColor3f(0,.8,0);
- else glColor3f(.8,1,.8);
- glVertex2f(last_x,last_y);
- glVertex2f(x,y);
- last_x=x; last_y=y;
- if (v==subj) break;
- if (v->isIntersection) is_outside = !is_outside;
+ for (GreinerV2f *curpoly=subj; curpoly; curpoly=curpoly->nextPoly) {
+ is_outside = true;
+ last_x=curpoly->x, last_y=curpoly->y;
+ if (clip_cyclic) is_outside = point_in_polygon(last_x, last_y, curpoly);
+ for (GreinerV2f *v=curpoly->next; v; v=v->next) {
+ float x=v->x, y=v->y;
+ if (is_outside) glColor3f(0,.8,0);
+ else glColor3f(.8,1,.8);
+ glVertex2f(last_x,last_y);
+ glVertex2f(x,y);
+ last_x=x; last_y=y;
+ if (v==curpoly) break;
+ if (v->isIntersection) is_outside = !is_outside;
+ }
}
glEnd();
- // Draw Subject polygon lines
+ // Draw Subject polygon verts
glPointSize(3);
glBegin(GL_POINTS);
glColor3f(0,1,0);
- first_iter = true;
- for (GreinerV2f *v=subj; v; v=v->next) {
- glVertex2f(v->x,v->y);
- if (!first_iter && v==subj) break;
- first_iter = false;
+ for (GreinerV2f *curpoly=subj; curpoly; curpoly=curpoly->nextPoly) {
+ last_x=curpoly->x, last_y=curpoly->y;
+ for (GreinerV2f *v=curpoly->next; v; v=v->next) {
+ float x=v->x, y=v->y;
+ if (!v->isBackbone) glColor3f(0,.8,0);
+ else glColor3f(1,1,0);
+ glVertex2f(x,y);
+ last_x=x; last_y=y;
+ if (v==curpoly) break;
+ if (v->isIntersection) is_outside = !is_outside;
+ }
}
glEnd();
@@ -204,10 +231,18 @@ void dump_polys_to_stdout() {
printf((v->next&&v->next!=clip)?"%f,%f, ":"%f,%f};\n",v->x,v->y);
if (v->next==clip) break;
}
- printf("std::vector<float> subj_verts = {");
- for (GreinerV2f *v=subj; v; v=v->next) {
- printf((v->next&&v->next!=subj)?"%f,%f, ":"%f,%f};\n",v->x,v->y);
- if (v->next==subj) break;
+ int subj_poly_num = 0;
+ for (GreinerV2f *subj_poly=subj; subj_poly; subj_poly=subj->nextPoly) {
+ printf("std::vector<float> subj%i = {", subj_poly_num);
+ for (GreinerV2f *v=subj_poly; v; v=v->next) {
+ printf((v->next&&v->next!=subj)?"%f,%f, ":"%f,%f};\n",v->x,v->y);
+ if (v->next==subj_poly) break;
+ }
+ subj_poly_num++;
+ }
+ printf("std::vector<std::vector<float>> subj_polys = {");
+ for (int i=0; i<subj_poly_num; i++) {
+ printf((i!=subj_poly_num-1)?"subj%i,":"subj%i};\n",i);
}
printf("std::vector<float> inout_pts = {");
for (size_t i=0,l=inout_pts.size()/2; i<l; i++) {
@@ -215,21 +250,44 @@ void dump_polys_to_stdout() {
}
}
void toggle_cyclic(GreinerV2f *curve) {
- if (curve->prev) { // is cyclic
- curve->prev->next = nullptr;
- curve->prev = nullptr;
- } else {
- GreinerV2f *last = curve;
- while (last->next) last = last->next;
- last->next = curve;
- curve->prev = last;
+ for (; curve; curve=curve->nextPoly) {
+ if (curve->prev) { // is cyclic
+ curve->prev->next = nullptr;
+ curve->prev = nullptr;
+ } else {
+ GreinerV2f *last = curve;
+ while (last->next) last = last->next;
+ last->next = curve;
+ curve->prev = last;
+ }
}
clip_cyclic = bool(clip->prev);
subj_cyclic = bool(subj->prev);
glutPostRedisplay();
}
void delete_last_selected_vert() {
- if (!grabbed_vert || grabbed_vert==clip || grabbed_vert==subj) return;
+ // Don't allow #subj verts or #clip verts -> 0
+ if (!grabbed_vert || grabbed_vert==clip) return;
+ if (grabbed_vert==subj) {
+ if (grabbed_vert->nextPoly) {
+ subj = grabbed_vert->nextPoly;
+ delete grabbed_vert;
+ glutPostRedisplay();
+ return;
+ }
+ else return;
+ }
+ // Did we grab a vert along the subject polygon backbone?
+ for (GreinerV2f *v = subj; v->nextPoly; v=v->nextPoly) {
+ if (grabbed_vert==v->nextPoly) {
+ v->nextPoly = grabbed_vert->nextPoly;
+ delete grabbed_vert;
+ glutPostRedisplay();
+ return;
+ }
+ }
+ // Otherwise we just have to worry about the doubly-linked-list of intra-polygon
+ // verts
GreinerV2f *next=grabbed_vert->next, *prev=grabbed_vert->prev;
if (next && prev) {
prev->next = next;
@@ -285,12 +343,8 @@ void GLUT_specialkey(int ch, int x, int y) {
void create_pt(float sx, float sy) {
if (!grabbed_vert) return;
GreinerV2f *last_vert = grabbed_vert;
- while (last_vert->next && last_vert->next!=clip && last_vert->next!=subj)
+ while (last_vert->next && !last_vert->isBackbone)
last_vert = last_vert->next;
- GreinerV2f *clip_last = clip;
- while (clip_last->next && clip_last->next!=clip) clip_last = clip_last->next;
- GreinerV2f *subj_last = subj;
- while (subj_last->next && subj_last->next!=subj) subj_last = subj_last->next;
GreinerV2f *v = new GreinerV2f();
v->x = sx;
v->y = sy;
@@ -320,15 +374,17 @@ void initiate_pt_drag_if_near_pt(float sx, float sy) {
}
if (v->next==clip) break;
}
- for (GreinerV2f *v=subj; v; v=v->next) {
- float dx = v->x - sx;
- float dy = v->y - sy;
- float dist = sqrt(dx*dx + dy*dy);
- if (dist<closest_dist) {
- closest_dist = dist;
- closest_vert = v;
+ for (GreinerV2f *poly=subj; poly; poly=poly->nextPoly) {
+ for (GreinerV2f *v=poly; v; v=v->next) {
+ float dx = v->x - sx;
+ float dy = v->y - sy;
+ float dist = sqrt(dx*dx + dy*dy);
+ if (dist<closest_dist) {
+ closest_dist = dist;
+ closest_vert = v;
+ }
+ if (v->next==poly) break;
}
- if (v->next==subj) break;
}
if (debug) printf("Nearest point to mousedown (%f)\n",closest_dist);
grabbed_vert = (closest_dist<.025) ? closest_vert : nullptr;
More information about the Bf-blender-cvs
mailing list