Dev Implementation
From AvoCADoWiki
Contents |
[edit]
Conceptual overview of Constructing a 3D Solid
- 1. Start a 2D-Sketch on an existing plane (or XY, YZ, XZ if no other planes have been created)
- 2. Place and adjust parameters of 2D-Tools comprised entirely of 2D-Prims (Arc, Line, Quadratic, Cubic, etc.)
- 3. Find all unique closed regions where 2D-Prims intersect
- 4. Decompose regions and into convex polygons (curves are now discretized; too bad)
- 5. Use a 2Dto3D-Tool on the 2D-Sketch to select regions/primitives for construction
- 6. Build a "Constructive Solid Geometry" (CSG) solid model from the regions/primitives/2Dto3D-Tool
- 7. Union/intersection/subtraction with the new CSG solid model and the existing part's solid model.
[edit]
User Interface
[edit]
Menuet (mode based menu system)
The hierarchy for the menuet is laid out as follows:
- Project
- Share (present, sync, etc.)
- Group (multiple parts)
- Part (the basic 3D component)
- Sketch (make 2D drawing)
- Build (2D->3D features)
- Modify (3D->3D modifications)
- Part (the basic 3D component)
[edit]
Major Algorithms
[edit]
CSG Boolean Operations
Error creating thumbnail: convert: unable to open image `/home/groups/a/av/avocado-cad/htdocs/wiki/images/0/09/CSG.png': No such file or directory. convert: unable to open file `/home/groups/a/av/avocado-cad/htdocs/wiki/images/0/09/CSG.png'. convert: missing an image filename `/home/groups/a/av/avocado-cad/htdocs/wiki/images/thumb/0/09/CSG.png/180px-CSG.png'.
Left to Right: 2 solids, CSG intersection, CSG union, CSG subtraction
Constructive Solid Geometry -- Union, Intersection, and Subtractions are performed via the algorithm described in:
Laidlaw, Trumbore, and Hughes "Constructive Solid Geometry for Polyhedral Objects" SIGGRAPH 1986, Volume 20, Number 4, pp.161-170
In a nutshell, two solids (comprised of faces to make a water-tight shell) are compared. Each face (a set of convex, coplanar, noncollinear polygons) is checked for intersection with the other solid. If an intersection is found, the line of intersection is computed and checked for overlap between the faces. Each face is then divided into additional convex coplanar polygons so that no polygons intersect. Once both solids have been subdivided to eliminate polygon intersection, each polygon is classified via ray-casting. Depending on the closest polygon, if any, that the ray intersects, each face is determined to be: - inside (polygonA is inside solidB) - outside (polygonA is outside solidB) - opposite,same (polygonA is opposite or the same as what is in solidB). Boolean operations (Union, Intersection, Subtraction) are then performed by only including certain polygon types.
[edit]
Region Formation from list of 2D Primitives
After a sketch has been constructed (a list of feature2D, which themselves are composed of 2D primitives) it is important to be able to find all of the 2D regions that it defines. These 2D regions can then be used to extrude parts of the sketch and create faces on the part.
overview of 2D region formation from 2D primitives. // 1. find intersections of all prim2D and split them so that none overlap (except at endpoints). // 2. only keep unique Prim2D. // 3. get rid of all prim2D that do not connect to others (or themselves) at both ends. // these are referred to as "dangling" prim2D. // // 4. start from each prim2D still remaining, and walk down connecting prim2D, always taking // the left-most turn possible when the elements branch. // 5. check to see what the total angle was for the cycle (is it clockwise?). // 6. if the cycle was clockwise (!isCCW) then keep it and consume elements in that direction. // // 7. perform steps 4,5,6 again but starting at the opposite end of the initial prim2D. // // 8. there is a chance for duplicate cycles, but in opposite direction.. make sure these // duplicates are removed. // // 9. all cycles are of minimal area and unique!... EXCEPT, fully enclosed regions. // (e.g., a circle withing a circle) // check to see if every point of each region is within any other region. // 10. cut the larger region to go around the inner region. // // 11. repeat steps 8,9 until there are no more cuts to be made. //
[edit]
Concave to Convex Polygon Tessellation
Error creating thumbnail: convert: unable to open image `/home/groups/a/av/avocado-cad/htdocs/wiki/images/4/42/Convexize.png': No such file or directory. convert: unable to open file `/home/groups/a/av/avocado-cad/htdocs/wiki/images/4/42/Convexize.png'. convert: missing an image filename `/home/groups/a/av/avocado-cad/htdocs/wiki/images/thumb/4/42/Convexize.png/180px-Convexize.png'.
A concave polygon originally defined by a set of perimeter vertices has been "convexize"d, splitting it up into polygons which are all convex
pseudo-code for "convexize polygon" method
// coffeeshop back-of-napkin idea by Adam Kumpf, likely to have bugs!
// (but seems to work for pretty much anything I've thrown at it so far)
// "Convexize a Polygon"
pointList = list of all vertices given in order (clockwise, but may be concave)
while(at least 3 points to consider and index < numberOfPoints)
ptA,ptB,ptC starting at index%numberOfPoints
if(angle{ABC} > 0)
construct potential polygon(A,B,C)
if(poly doesn't overlap/contain any other point)
for(every remaining pointD)
if(angle{poly.LastLastPt, poly.LastPt, pointD} > 0 &&
angle{poly.LastPt, pointD, poly.firstPoint} > 0 &&
angle{pointD, poly.firstPoint, poly.secPoint} > 0)
if(poly doesn't contains any other point)
poly.add(ptD);
else
break;
else
break;
face.addPoly(poly);
remove all of poly's middle points from pointList
index = 0;
else
index++
else
index++;
[edit]
Perimeter Vertices from a set of Planar Polygons
Error creating thumbnail: convert: unable to open image `/home/groups/a/av/avocado-cad/htdocs/wiki/images/c/cd/Perimeter.png': No such file or directory. convert: unable to open file `/home/groups/a/av/avocado-cad/htdocs/wiki/images/c/cd/Perimeter.png'. convert: missing an image filename `/home/groups/a/av/avocado-cad/htdocs/wiki/images/thumb/c/cd/Perimeter.png/180px-Perimeter.png'.
Perimeter formed from a set of non-overlapping polygons in the same plane
A face on a part may be split up into many polygons due to rendering limitations of concave polygons. To draw the perimeter of this multi-polygon planar face, the following algorithm seems to work quite nicely.
// pseudo-code for constructing a list of perimeter vertices from the set of planar, non-overlapping polygons.
List P // list of perimeter vertices
List G // list of polygons (gets modified, use a copy if G should be untouched)
int lastSize = infinite;
boolean isFirstTime = true;
while(lastSize > G.size){
lastSize = G.size;
for(n=0; n<G.size; n++){
L = G.get(n); // L = a polygon in G (the list of all remaining polygons to add)
if(isFirstTime){
add all points of L to P;
G.remove(L);
isFirstTime = false;
}else{
// look for a shared edge, if it exists, squish polygons together
boolean gotoNext = false;
for(i=0; i<L.totalVertices; i++){
vertPolyA = L.get(i);
for(j=0; j<P.totalVertices; j++){
vertPerimA = P.get(j);
if(vertPolyA == vertPerimA){
vertPolyB = L.get(i+1);
vertPerimB = P.get(j-1);
if(vertPolyB == vertPerimB){
// edge matched!
for(q=i; q>(i-L.totalVertices+1); q--){
P.add(j, L.get(q)); // add vertex to perimeter at location "j"
}
G.remove(L);
gotoNext = true;
}
}
if(gotoNext) break; // start looking from beginning again since P has changed.
}
if(gotoNext) break; // start looking from beginning again since P has changed.
}
}
}
P now has the set of perimeter vertices

