|
Blender
V2.59
|
00001 /* 00002 * $Id: editmesh_add.c 36368 2011-04-28 09:50:57Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2004 by Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00036 #include <stdlib.h> 00037 #include <string.h> 00038 #include <math.h> 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "DNA_meshdata_types.h" 00043 #include "DNA_object_types.h" 00044 #include "DNA_scene_types.h" 00045 00046 #include "RNA_define.h" 00047 #include "RNA_access.h" 00048 #include "RNA_enum_types.h" 00049 00050 #include "BLI_blenlib.h" 00051 #include "BLI_math.h" 00052 #include "BLI_editVert.h" 00053 #include "BLI_utildefines.h" 00054 00055 #include "BKE_context.h" 00056 #include "BKE_depsgraph.h" 00057 #include "BKE_library.h" 00058 #include "BKE_mesh.h" 00059 #include "BKE_report.h" 00060 00061 #include "WM_api.h" 00062 #include "WM_types.h" 00063 00064 #include "ED_mesh.h" 00065 #include "ED_screen.h" 00066 #include "ED_transform.h" 00067 #include "ED_view3d.h" 00068 #include "ED_object.h" 00069 00070 #include "mesh_intern.h" 00071 00072 /* bpymenu removed XXX */ 00073 00074 /* XXX */ 00075 #define add_numbut(a, b, c, d, e, f, g) {} 00076 /* XXX */ 00077 00078 static float icovert[12][3] = { 00079 {0.0f,0.0f,-200.0f}, 00080 {144.72f, -105.144f,-89.443f}, 00081 {-55.277f, -170.128,-89.443f}, 00082 {-178.885f,0.0f,-89.443f}, 00083 {-55.277f,170.128f,-89.443f}, 00084 {144.72f,105.144f,-89.443f}, 00085 {55.277f,-170.128f,89.443f}, 00086 {-144.72f,-105.144f,89.443f}, 00087 {-144.72f,105.144f,89.443f}, 00088 {55.277f,170.128f,89.443f}, 00089 {178.885f,0.0f,89.443f}, 00090 {0.0f,0.0f,200.0f} 00091 }; 00092 static short icoface[20][3] = { 00093 {2,0,1}, 00094 {1,0,5}, 00095 {3,0,2}, 00096 {4,0,3}, 00097 {5,0,4}, 00098 {1,5,10}, 00099 {2,1,6}, 00100 {3,2,7}, 00101 {4,3,8}, 00102 {5,4,9}, 00103 {6,1,10}, 00104 {7,2,6}, 00105 {8,3,7}, 00106 {9,4,8}, 00107 {10,5,9}, 00108 {6,10,11}, 00109 {7,6,11}, 00110 {8,7,11}, 00111 {9,8,11}, 00112 {10,9,11} 00113 }; 00114 00115 /* *************** add-click-mesh (extrude) operator ************** */ 00116 00117 static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event) 00118 { 00119 ViewContext vc; 00120 EditVert *eve; 00121 float min[3], max[3]; 00122 int done= 0; 00123 short use_proj; 00124 00125 em_setup_viewcontext(C, &vc); 00126 00127 use_proj= (vc.scene->toolsettings->snap_flag & SCE_SNAP) && (vc.scene->toolsettings->snap_mode==SCE_SNAP_MODE_FACE); 00128 00129 invert_m4_m4(vc.obedit->imat, vc.obedit->obmat); 00130 00131 INIT_MINMAX(min, max); 00132 00133 for(eve= vc.em->verts.first; eve; eve= eve->next) { 00134 if(eve->f & SELECT) { 00135 DO_MINMAX(eve->co, min, max); 00136 done= 1; 00137 } 00138 } 00139 00140 /* call extrude? */ 00141 if(done) { 00142 const short rot_src= RNA_boolean_get(op->ptr, "rotate_source"); 00143 EditEdge *eed; 00144 float vec[3], cent[3], mat[3][3]; 00145 float nor[3]= {0.0, 0.0, 0.0}; 00146 00147 /* 2D normal calc */ 00148 float mval_f[2]; 00149 00150 mval_f[0]= (float)event->mval[0]; 00151 mval_f[1]= (float)event->mval[1]; 00152 00153 done= 0; 00154 00155 /* calculate the normal for selected edges */ 00156 for(eed= vc.em->edges.first; eed; eed= eed->next) { 00157 if(eed->f & SELECT) { 00158 float co1[3], co2[3]; 00159 mul_v3_m4v3(co1, vc.obedit->obmat, eed->v1->co); 00160 mul_v3_m4v3(co2, vc.obedit->obmat, eed->v2->co); 00161 project_float_noclip(vc.ar, co1, co1); 00162 project_float_noclip(vc.ar, co2, co2); 00163 00164 /* 2D rotate by 90d while adding. 00165 * (x, y) = (y, -x) 00166 * 00167 * accumulate the screenspace normal in 2D, 00168 * with screenspace edge length weighting the result. */ 00169 if(line_point_side_v2(co1, co2, mval_f) >= 0.0f) { 00170 nor[0] += (co1[1] - co2[1]); 00171 nor[1] += -(co1[0] - co2[0]); 00172 } 00173 else { 00174 nor[0] += (co2[1] - co1[1]); 00175 nor[1] += -(co2[0] - co1[0]); 00176 } 00177 done= 1; 00178 } 00179 } 00180 00181 if(done) { 00182 float view_vec[3], cross[3]; 00183 00184 /* convert the 2D nomal into 3D */ 00185 mul_mat3_m4_v3(vc.rv3d->viewinv, nor); /* worldspace */ 00186 mul_mat3_m4_v3(vc.obedit->imat, nor); /* local space */ 00187 00188 /* correct the normal to be aligned on the view plane */ 00189 copy_v3_v3(view_vec, vc.rv3d->viewinv[2]); 00190 mul_mat3_m4_v3(vc.obedit->imat, view_vec); 00191 cross_v3_v3v3(cross, nor, view_vec); 00192 cross_v3_v3v3(nor, view_vec, cross); 00193 normalize_v3(nor); 00194 } 00195 00196 /* center */ 00197 mid_v3_v3v3(cent, min, max); 00198 copy_v3_v3(min, cent); 00199 00200 mul_m4_v3(vc.obedit->obmat, min); // view space 00201 view3d_get_view_aligned_coordinate(&vc, min, event->mval, TRUE); 00202 mul_m4_v3(vc.obedit->imat, min); // back in object space 00203 00204 sub_v3_v3(min, cent); 00205 00206 /* calculate rotation */ 00207 unit_m3(mat); 00208 if(done) { 00209 float dot; 00210 00211 copy_v3_v3(vec, min); 00212 normalize_v3(vec); 00213 dot= INPR(vec, nor); 00214 00215 if( fabs(dot)<0.999) { 00216 float cross[3], si, q1[4]; 00217 00218 cross_v3_v3v3(cross, nor, vec); 00219 normalize_v3(cross); 00220 dot= 0.5f*saacos(dot); 00221 00222 /* halve the rotation if its applied twice */ 00223 if(rot_src) dot *= 0.5f; 00224 00225 si= (float)sin(dot); 00226 q1[0]= (float)cos(dot); 00227 q1[1]= cross[0]*si; 00228 q1[2]= cross[1]*si; 00229 q1[3]= cross[2]*si; 00230 quat_to_mat3( mat,q1); 00231 } 00232 } 00233 00234 if(rot_src) { 00235 rotateflag(vc.em, SELECT, cent, mat); 00236 /* also project the source, for retopo workflow */ 00237 if(use_proj) 00238 EM_project_snap_verts(C, vc.ar, vc.obedit, vc.em); 00239 } 00240 00241 extrudeflag(vc.obedit, vc.em, SELECT, nor, 0); 00242 rotateflag(vc.em, SELECT, cent, mat); 00243 translateflag(vc.em, SELECT, min); 00244 00245 recalc_editnormals(vc.em); 00246 } 00247 else if(vc.em->selectmode & SCE_SELECT_VERTEX) { 00248 00249 float imat[4][4]; 00250 const float *curs= give_cursor(vc.scene, vc.v3d); 00251 00252 copy_v3_v3(min, curs); 00253 view3d_get_view_aligned_coordinate(&vc, min, event->mval, TRUE); 00254 00255 eve= addvertlist(vc.em, 0, NULL); 00256 00257 invert_m4_m4(imat, vc.obedit->obmat); 00258 mul_v3_m4v3(eve->co, imat, min); 00259 00260 eve->f= SELECT; 00261 } 00262 00263 if(use_proj) 00264 EM_project_snap_verts(C, vc.ar, vc.obedit, vc.em); 00265 00266 WM_event_add_notifier(C, NC_GEOM|ND_DATA, vc.obedit->data); 00267 DAG_id_tag_update(vc.obedit->data, 0); 00268 00269 return OPERATOR_FINISHED; 00270 } 00271 00272 void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot) 00273 { 00274 /* identifiers */ 00275 ot->name= "Duplicate or Extrude at 3D Cursor"; 00276 ot->description= "Duplicate and extrude selected vertices, edges or faces towards 3D Cursor"; 00277 ot->idname= "MESH_OT_dupli_extrude_cursor"; 00278 00279 /* api callbacks */ 00280 ot->invoke= dupli_extrude_cursor; 00281 ot->poll= ED_operator_editmesh; 00282 00283 /* flags */ 00284 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00285 00286 RNA_def_boolean(ot->srna, "rotate_source", 1, "Rotate Source", "Rotate initial selection giving better shape"); 00287 } 00288 00289 00290 /* ********************** */ 00291 00292 /* selected faces get hidden edges */ 00293 static int make_fgon(EditMesh *em, wmOperator *op, int make) 00294 { 00295 EditFace *efa; 00296 EditEdge *eed; 00297 EditVert *eve; 00298 float *nor=NULL; // reference 00299 int done=0; 00300 00301 if(make==0) { 00302 for(efa= em->faces.first; efa; efa= efa->next) { 00303 if(efa->f & SELECT) { 00304 efa->fgonf= 0; 00305 efa->e1->h &= ~EM_FGON; 00306 efa->e2->h &= ~EM_FGON; 00307 efa->e3->h &= ~EM_FGON; 00308 if(efa->e4) efa->e4->h &= ~EM_FGON; 00309 done= 1; 00310 } 00311 } 00312 EM_fgon_flags(em); // redo flags and indices for fgons 00313 00314 return done; 00315 } 00316 00317 /* tagging edges. rule is: 00318 - edge used by exactly 2 selected faces 00319 - no vertices allowed with only tagged edges (return) 00320 - face normals are allowed to difffer 00321 00322 */ 00323 for(eed= em->edges.first; eed; eed= eed->next) { 00324 eed->f1= 0; // amount of selected 00325 eed->f2= 0; // amount of unselected 00326 } 00327 00328 for(efa= em->faces.first; efa; efa= efa->next) { 00329 if(efa->f & SELECT) { 00330 if(nor==NULL) nor= efa->n; 00331 if(efa->e1->f1 < 3) efa->e1->f1++; 00332 if(efa->e2->f1 < 3) efa->e2->f1++; 00333 if(efa->e3->f1 < 3) efa->e3->f1++; 00334 if(efa->e4 && efa->e4->f1 < 3) efa->e4->f1++; 00335 } 00336 else { 00337 if(efa->e1->f2 < 3) efa->e1->f2++; 00338 if(efa->e2->f2 < 3) efa->e2->f2++; 00339 if(efa->e3->f2 < 3) efa->e3->f2++; 00340 if(efa->e4 && efa->e4->f2 < 3) efa->e4->f2++; 00341 } 00342 } 00343 // now eed->f1 becomes tagged edge 00344 for(eed= em->edges.first; eed; eed= eed->next) { 00345 if(eed->f1==2 && eed->f2==0) eed->f1= 1; 00346 else eed->f1= 0; 00347 } 00348 00349 // no vertices allowed with only tagged edges 00350 for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0; 00351 for(eed= em->edges.first; eed; eed= eed->next) { 00352 if(eed->f1) { 00353 eed->v1->f1 |= 1; 00354 eed->v2->f1 |= 1; 00355 } 00356 else { 00357 eed->v1->f1 |= 2; 00358 eed->v2->f1 |= 2; 00359 } 00360 } 00361 for(eve= em->verts.first; eve; eve= eve->next) { 00362 if(eve->f1==1) break; 00363 } 00364 if(eve) { 00365 BKE_report(op->reports, RPT_WARNING, "Cannot make a polygon with interior vertices"); 00366 return 0; 00367 } 00368 00369 // check for faces 00370 if(nor==NULL) { 00371 BKE_report(op->reports, RPT_WARNING, "No faces were selected to make FGon"); 00372 return 0; 00373 } 00374 00375 // and there we go 00376 for(eed= em->edges.first; eed; eed= eed->next) { 00377 if(eed->f1) { 00378 eed->h |= EM_FGON; 00379 done= 1; 00380 } 00381 } 00382 00383 if(done) 00384 EM_fgon_flags(em); // redo flags and indices for fgons 00385 return done; 00386 } 00387 00388 static int make_fgon_exec(bContext *C, wmOperator *op) 00389 { 00390 Object *obedit= CTX_data_edit_object(C); 00391 EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); 00392 00393 if( make_fgon(em, op, 1) ) { 00394 DAG_id_tag_update(obedit->data, 0); 00395 WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); 00396 00397 BKE_mesh_end_editmesh(obedit->data, em); 00398 return OPERATOR_FINISHED; 00399 } 00400 00401 BKE_mesh_end_editmesh(obedit->data, em); 00402 return OPERATOR_CANCELLED; 00403 } 00404 00405 void MESH_OT_fgon_make(struct wmOperatorType *ot) 00406 { 00407 /* identifiers */ 00408 ot->name= "Make F-gon"; 00409 ot->description= "Make fgon from selected faces"; 00410 ot->idname= "MESH_OT_fgon_make"; 00411 00412 /* api callbacks */ 00413 ot->exec= make_fgon_exec; 00414 ot->poll= ED_operator_editmesh; 00415 00416 /* flags */ 00417 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00418 } 00419 00420 static int clear_fgon_exec(bContext *C, wmOperator *op) 00421 { 00422 Object *obedit= CTX_data_edit_object(C); 00423 EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); 00424 00425 if( make_fgon(em, op, 0) ) { 00426 DAG_id_tag_update(obedit->data, 0); 00427 WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); 00428 00429 BKE_mesh_end_editmesh(obedit->data, em); 00430 return OPERATOR_FINISHED; 00431 } 00432 00433 BKE_mesh_end_editmesh(obedit->data, em); 00434 return OPERATOR_CANCELLED; 00435 } 00436 00437 void MESH_OT_fgon_clear(struct wmOperatorType *ot) 00438 { 00439 /* identifiers */ 00440 ot->name= "Clear F-gon"; 00441 ot->description= "Clear fgon from selected face"; 00442 ot->idname= "MESH_OT_fgon_clear"; 00443 00444 /* api callbacks */ 00445 ot->exec= clear_fgon_exec; 00446 ot->poll= ED_operator_editmesh; 00447 00448 /* flags */ 00449 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00450 } 00451 00452 /* precondition; 4 vertices selected, check for 4 edges and create face */ 00453 static EditFace *addface_from_edges(EditMesh *em) 00454 { 00455 EditEdge *eed, *eedar[4]={NULL, NULL, NULL, NULL}; 00456 EditVert *v1=NULL, *v2=NULL, *v3=NULL, *v4=NULL; 00457 int a; 00458 00459 /* find the 4 edges */ 00460 for(eed= em->edges.first; eed; eed= eed->next) { 00461 if( (eed->f & SELECT) || (eed->v1->f & eed->v2->f & SELECT) ) { 00462 if(eedar[0]==NULL) eedar[0]= eed; 00463 else if(eedar[1]==NULL) eedar[1]= eed; 00464 else if(eedar[2]==NULL) eedar[2]= eed; 00465 else eedar[3]= eed; 00466 00467 } 00468 } 00469 00470 00471 if(eedar[3]) { 00472 /* first 2 points */ 00473 v1= eedar[0]->v1; 00474 v2= eedar[0]->v2; 00475 00476 /* find the 2 edges connected to first edge */ 00477 for(a=1; a<4; a++) { 00478 if( eedar[a]->v1 == v2) v3= eedar[a]->v2; 00479 else if(eedar[a]->v2 == v2) v3= eedar[a]->v1; 00480 else if( eedar[a]->v1 == v1) v4= eedar[a]->v2; 00481 else if(eedar[a]->v2 == v1) v4= eedar[a]->v1; 00482 } 00483 00484 /* verify if last edge exists */ 00485 if(v3 && v4) { 00486 for(a=1; a<4; a++) { 00487 if( eedar[a]->v1==v3 && eedar[a]->v2==v4) break; 00488 if( eedar[a]->v2==v3 && eedar[a]->v1==v4) break; 00489 } 00490 if(a!=4) { 00491 return addfacelist(em, v1, v2, v3, v4, NULL, NULL); 00492 } 00493 } 00494 } 00495 return NULL; 00496 } 00497 00498 /* ******************************* */ 00499 00500 /* this also allows to prevent triangles being made in quads */ 00501 static int compareface_overlaps(EditFace *vl1, EditFace *vl2) 00502 { 00503 EditVert *v1, *v2, *v3, *v4; 00504 int equal= 0; 00505 00506 v1= vl2->v1; 00507 v2= vl2->v2; 00508 v3= vl2->v3; 00509 v4= vl2->v4; 00510 00511 if(vl1==vl2) return 0; 00512 00513 if(v4==NULL && vl1->v4==NULL) { 00514 if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1) equal++; 00515 if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2) equal++; 00516 if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3) equal++; 00517 } 00518 else { 00519 if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1 || vl1->v4==v1) equal++; 00520 if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2 || vl1->v4==v2) equal++; 00521 if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3 || vl1->v4==v3) equal++; 00522 if(vl1->v1==v4 || vl1->v2==v4 || vl1->v3==v4 || vl1->v4==v4) equal++; 00523 } 00524 00525 if(v4 && vl1->v4) { 00526 if(equal==4) return 1; 00527 } 00528 else 00529 if(equal>=3) return 1; 00530 00531 return 0; 00532 } 00533 00534 /* checks for existence, and for tria overlapping inside quad */ 00535 static EditFace *exist_face_overlaps(EditMesh *em, EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4) 00536 { 00537 EditFace *efa, efatest; 00538 00539 efatest.v1= v1; 00540 efatest.v2= v2; 00541 efatest.v3= v3; 00542 efatest.v4= v4; 00543 00544 efa= em->faces.first; 00545 while(efa) { 00546 if(compareface_overlaps(&efatest, efa)) return efa; 00547 efa= efa->next; 00548 } 00549 return NULL; 00550 } 00551 00552 /* will be new face smooth or solid? depends on smoothness of face neighbours 00553 * of new face, if function return 1, then new face will be smooth, when functio 00554 * will return zero, then new face will be solid */ 00555 static void fix_new_face(EditMesh *em, EditFace *eface) 00556 { 00557 struct EditFace *efa; 00558 struct EditEdge *eed=NULL; 00559 struct EditVert *v1 = eface->v1, *v2 = eface->v2, *v3 = eface->v3, *v4 = eface->v4; 00560 struct EditVert *ev1=NULL, *ev2=NULL; 00561 short smooth=0; /* "total smoothnes" of faces in neighbourhood */ 00562 short coef; /* "weight" of smoothness */ 00563 short count=0; /* number of edges with same direction as eface */ 00564 short vi00=0, vi01=0, vi10=0, vi11=0; /* vertex indexes */ 00565 00566 efa = em->faces.first; 00567 00568 while(efa) { 00569 00570 if(efa==eface) { 00571 efa = efa->next; 00572 continue; 00573 } 00574 00575 coef = 0; 00576 ev1 = ev2 = NULL; 00577 eed = NULL; 00578 00579 if(efa->v1==v1 || efa->v2==v1 || efa->v3==v1 || efa->v4==v1) { 00580 ev1 = v1; 00581 coef++; 00582 } 00583 if(efa->v1==v2 || efa->v2==v2 || efa->v3==v2 || efa->v4==v2) { 00584 if(ev1) ev2 = v2; 00585 else ev1 = v2; 00586 coef++; 00587 } 00588 if(efa->v1==v3 || efa->v2==v3 || efa->v3==v3 || efa->v4==v3) { 00589 if(coef<2) { 00590 if(ev1) ev2 = v3; 00591 else ev1 = v3; 00592 } 00593 coef++; 00594 } 00595 if((v4) && (efa->v1==v4 || efa->v2==v4 || efa->v3==v4 || efa->v4==v4)) { 00596 if(ev1 && coef<2) ev2 = v4; 00597 coef++; 00598 } 00599 00600 /* "democracy" of smoothness */ 00601 if(efa->flag & ME_SMOOTH) 00602 smooth += coef; 00603 else 00604 smooth -= coef; 00605 00606 /* try to find edge using vertexes ev1 and ev2 */ 00607 if((ev1) && (ev2) && (ev1!=ev2)) eed = findedgelist(em, ev1, ev2); 00608 00609 /* has bordering edge of efa same direction as edge of eface ? */ 00610 if(eed) { 00611 if(eed->v1==v1) vi00 = 1; 00612 else if(eed->v1==v2) vi00 = 2; 00613 else if(eed->v1==v3) vi00 = 3; 00614 else if(v4 && eed->v1==v4) vi00 = 4; 00615 00616 if(eed->v2==v1) vi01 = 1; 00617 else if(eed->v2==v2) vi01 = 2; 00618 else if(eed->v2==v3) vi01 = 3; 00619 else if(v4 && eed->v2==v4) vi01 = 4; 00620 00621 if(v4) { 00622 if(vi01==1 && vi00==4) vi00 = 0; 00623 if(vi01==4 && vi00==1) vi01 = 0; 00624 } 00625 else { 00626 if(vi01==1 && vi00==3) vi00 = 0; 00627 if(vi01==3 && vi00==1) vi01 = 0; 00628 } 00629 00630 if(eed->v1==efa->v1) vi10 = 1; 00631 else if(eed->v1==efa->v2) vi10 = 2; 00632 else if(eed->v1==efa->v3) vi10 = 3; 00633 else if(efa->v4 && eed->v1==efa->v4) vi10 = 4; 00634 00635 if(eed->v2==efa->v1) vi11 = 1; 00636 else if(eed->v2==efa->v2) vi11 = 2; 00637 else if(eed->v2==efa->v3) vi11 = 3; 00638 else if(efa->v4 && eed->v2==efa->v4) vi11 = 4; 00639 00640 if(efa->v4) { 00641 if(vi11==1 && vi10==4) vi10 = 0; 00642 if(vi11==4 && vi10==1) vi11 = 0; 00643 } 00644 else { 00645 if(vi11==1 && vi10==3) vi10 = 0; 00646 if(vi11==3 && vi10==1) vi11 = 0; 00647 } 00648 00649 if(((vi00>vi01) && (vi10>vi11)) || 00650 ((vi00<vi01) && (vi10<vi11))) 00651 count++; 00652 else 00653 count--; 00654 } 00655 00656 efa = efa->next; 00657 } 00658 00659 /* set up smoothness according voting of face in neighbourhood */ 00660 if(smooth >= 0) 00661 eface->flag |= ME_SMOOTH; 00662 else 00663 eface->flag &= ~ME_SMOOTH; 00664 00665 /* flip face, when too much "face normals" in neighbourhood is different */ 00666 if(count > 0) { 00667 flipface(em, eface); 00668 } 00669 } 00670 00671 /* only adds quads or trias when there's edges already */ 00672 static void addfaces_from_edgenet(EditMesh *em) 00673 { 00674 EditVert *eve1, *eve2, *eve3, *eve4; 00675 00676 for(eve1= em->verts.first; eve1; eve1= eve1->next) { 00677 for(eve2= em->verts.first; (eve1->f & 1) && eve2; eve2= eve2->next) { 00678 if(findedgelist(em, eve1,eve2)) { 00679 for(eve3= em->verts.first; (eve2->f & 1) && eve3; eve3= eve3->next) { 00680 if((eve2!=eve3 && (eve3->f & 1) && findedgelist(em, eve1,eve3))) { 00681 EditEdge *sh_edge= NULL; 00682 EditVert *sh_vert= NULL; 00683 00684 sh_edge= findedgelist(em, eve2,eve3); 00685 00686 if(sh_edge) { /* Add a triangle */ 00687 if(!exist_face_overlaps(em, eve1,eve2,eve3,NULL)) 00688 fix_new_face(em, addfacelist(em, eve1,eve2,eve3,NULL,NULL,NULL)); 00689 } 00690 else { /* Check for a shared vertex */ 00691 for(eve4= em->verts.first; eve4; eve4= eve4->next) { 00692 if(eve4!=eve1 && eve4!=eve2 && eve4!=eve3 && (eve4->f & 1) && 00693 !findedgelist(em, eve1,eve4) && findedgelist(em, eve2,eve4) && 00694 findedgelist(em, eve3,eve4)) { 00695 sh_vert= eve4; 00696 break; 00697 } 00698 } 00699 00700 if(sh_vert) { 00701 if(sh_vert) { 00702 if(!exist_face_overlaps(em, eve1,eve2,eve4,eve3)) 00703 fix_new_face(em, addfacelist(em, eve1,eve2,eve4,eve3,NULL,NULL)); 00704 } 00705 } 00706 } 00707 } 00708 } 00709 } 00710 } 00711 } 00712 00713 EM_select_flush(em); 00714 00715 // XXX DAG_id_tag_update(obedit->data, 0); 00716 } 00717 00718 static void addedgeface_mesh(EditMesh *em, wmOperator *op) 00719 { 00720 EditVert *eve, *neweve[4]; 00721 EditEdge *eed; 00722 EditFace *efa; 00723 short amount=0; 00724 00725 /* how many selected ? */ 00726 if(em->selectmode & SCE_SELECT_EDGE) { 00727 /* in edge mode finding selected vertices means flushing down edge codes... */ 00728 /* can't make face with only edge selection info... */ 00729 EM_selectmode_set(em); 00730 } 00731 00732 for(eve= em->verts.first; eve; eve= eve->next) { 00733 if(eve->f & SELECT) { 00734 amount++; 00735 if(amount>4) break; 00736 neweve[amount-1]= eve; 00737 } 00738 } 00739 00740 if(amount==2) { 00741 eed= addedgelist(em, neweve[0], neweve[1], NULL); 00742 EM_select_edge(eed, 1); 00743 00744 // XXX DAG_id_tag_update(obedit->data, 0); 00745 return; 00746 } 00747 else if(amount > 4) { 00748 addfaces_from_edgenet(em); 00749 return; 00750 } 00751 else if(amount<2) { 00752 BKE_report(op->reports, RPT_WARNING, "More vertices are needed to make an edge/face"); 00753 return; 00754 } 00755 00756 efa= NULL; // check later 00757 00758 if(amount==3) { 00759 00760 if(exist_face_overlaps(em, neweve[0], neweve[1], neweve[2], NULL)==0) { 00761 efa= addfacelist(em, neweve[0], neweve[1], neweve[2], 0, NULL, NULL); 00762 EM_select_face(efa, 1); 00763 } 00764 else BKE_report(op->reports, RPT_WARNING, "The selected vertices already form a face"); 00765 } 00766 else if(amount==4) { 00767 /* this test survives when theres 2 triangles */ 00768 if(exist_face(em, neweve[0], neweve[1], neweve[2], neweve[3])==0) { 00769 int tria= 0; 00770 00771 /* remove trias if they exist, 4 cases.... */ 00772 if(exist_face(em, neweve[0], neweve[1], neweve[2], NULL)) tria++; 00773 if(exist_face(em, neweve[0], neweve[1], neweve[3], NULL)) tria++; 00774 if(exist_face(em, neweve[0], neweve[2], neweve[3], NULL)) tria++; 00775 if(exist_face(em, neweve[1], neweve[2], neweve[3], NULL)) tria++; 00776 00777 if(tria==2) join_triangles(em); 00778 else if(exist_face_overlaps(em, neweve[0], neweve[1], neweve[2], neweve[3])==0) { 00779 /* If there are 4 Verts, But more selected edges, we need to call addfaces_from_edgenet */ 00780 EditEdge *eedcheck; 00781 int count; 00782 count = 0; 00783 for(eedcheck= em->edges.first; eedcheck; eedcheck= eedcheck->next) { 00784 if(eedcheck->f & SELECT) { 00785 count++; 00786 } 00787 } 00788 00789 if(count++ > 4){ 00790 addfaces_from_edgenet(em); 00791 return; 00792 } else { 00793 /* if 4 edges exist, we just create the face, convex or not */ 00794 efa= addface_from_edges(em); 00795 if(efa==NULL) { 00796 00797 /* the order of vertices can be anything, 6 cases to check */ 00798 if( convex(neweve[0]->co, neweve[1]->co, neweve[2]->co, neweve[3]->co) ) { 00799 efa= addfacelist(em, neweve[0], neweve[1], neweve[2], neweve[3], NULL, NULL); 00800 } 00801 else if( convex(neweve[0]->co, neweve[2]->co, neweve[3]->co, neweve[1]->co) ) { 00802 efa= addfacelist(em, neweve[0], neweve[2], neweve[3], neweve[1], NULL, NULL); 00803 } 00804 else if( convex(neweve[0]->co, neweve[2]->co, neweve[1]->co, neweve[3]->co) ) { 00805 efa= addfacelist(em, neweve[0], neweve[2], neweve[1], neweve[3], NULL, NULL); 00806 } 00807 else if( convex(neweve[0]->co, neweve[1]->co, neweve[3]->co, neweve[2]->co) ) { 00808 efa= addfacelist(em, neweve[0], neweve[1], neweve[3], neweve[2], NULL, NULL); 00809 } 00810 else if( convex(neweve[0]->co, neweve[3]->co, neweve[2]->co, neweve[1]->co) ) { 00811 efa= addfacelist(em, neweve[0], neweve[3], neweve[2], neweve[1], NULL, NULL); 00812 } 00813 else if( convex(neweve[0]->co, neweve[3]->co, neweve[1]->co, neweve[2]->co) ) { 00814 efa= addfacelist(em, neweve[0], neweve[3], neweve[1], neweve[2], NULL, NULL); 00815 } 00816 else BKE_report(op->reports, RPT_WARNING, "cannot find nice quad from concave set of vertices"); 00817 00818 } 00819 } 00820 } 00821 else BKE_report(op->reports, RPT_WARNING, "The selected vertices already form a face"); 00822 } 00823 else BKE_report(op->reports, RPT_WARNING, "The selected vertices already form a face"); 00824 } 00825 00826 if(efa) { 00827 EM_select_face(efa, 1); 00828 00829 fix_new_face(em, efa); 00830 00831 recalc_editnormals(em); 00832 } 00833 } 00834 00835 static int addedgeface_mesh_exec(bContext *C, wmOperator *op) 00836 { 00837 Object *obedit= CTX_data_edit_object(C); 00838 EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); 00839 00840 addedgeface_mesh(em, op); 00841 00842 DAG_id_tag_update(obedit->data, 0); 00843 WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); 00844 00845 BKE_mesh_end_editmesh(obedit->data, em); 00846 return OPERATOR_FINISHED; 00847 } 00848 00849 void MESH_OT_edge_face_add(wmOperatorType *ot) 00850 { 00851 /* identifiers */ 00852 ot->name= "Make Edge/Face"; 00853 ot->description= "Add an edge or face to selected"; 00854 ot->idname= "MESH_OT_edge_face_add"; 00855 00856 /* api callbacks */ 00857 ot->exec= addedgeface_mesh_exec; 00858 ot->poll= ED_operator_editmesh; 00859 00860 /* flags */ 00861 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00862 00863 } 00864 00865 00866 00867 /* ************************ primitives ******************* */ 00868 00869 // HACK: these can also be found in cmoview.tga.c, but are here so that they can be found by linker 00870 // this hack is only used so that scons+mingw + split-sources hack works 00871 // ------------------------------- start copied code 00872 /* these are not the monkeys you are looking for */ 00873 static int monkeyo= 4; 00874 static int monkeynv= 271; 00875 static int monkeynf= 250; 00876 static signed char monkeyv[271][3]= { 00877 {-71,21,98},{-63,12,88},{-57,7,74},{-82,-3,79},{-82,4,92}, 00878 {-82,17,100},{-92,21,102},{-101,12,95},{-107,7,83}, 00879 {-117,31,84},{-109,31,95},{-96,31,102},{-92,42,102}, 00880 {-101,50,95},{-107,56,83},{-82,66,79},{-82,58,92}, 00881 {-82,46,100},{-71,42,98},{-63,50,88},{-57,56,74}, 00882 {-47,31,72},{-55,31,86},{-67,31,97},{-66,31,99}, 00883 {-70,43,100},{-82,48,103},{-93,43,105},{-98,31,105}, 00884 {-93,20,105},{-82,31,106},{-82,15,103},{-70,20,100}, 00885 {-127,55,95},{-127,45,105},{-127,-87,94},{-127,-41,100}, 00886 {-127,-24,102},{-127,-99,92},{-127,52,77},{-127,73,73}, 00887 {-127,115,-70},{-127,72,-109},{-127,9,-106},{-127,-49,-45}, 00888 {-101,-24,72},{-87,-56,73},{-82,-89,73},{-80,-114,68}, 00889 {-85,-121,67},{-104,-124,71},{-127,-126,74},{-71,-18,68}, 00890 {-46,-5,69},{-21,19,57},{-17,55,76},{-36,62,80}, 00891 {-64,77,88},{-86,97,94},{-107,92,97},{-119,63,96}, 00892 {-106,53,99},{-111,39,98},{-101,12,95},{-79,2,90}, 00893 {-64,8,86},{-47,24,83},{-45,38,83},{-50,48,85}, 00894 {-72,56,92},{-95,60,97},{-127,-98,94},{-113,-92,94}, 00895 {-112,-107,91},{-119,-113,89},{-127,-114,88},{-127,-25,96}, 00896 {-127,-18,95},{-114,-19,95},{-111,-29,96},{-116,-37,95}, 00897 {-76,-6,86},{-48,7,80},{-34,26,77},{-32,48,84}, 00898 {-39,53,93},{-71,70,102},{-87,82,107},{-101,79,109}, 00899 {-114,55,108},{-111,-13,104},{-100,-57,91},{-95,-90,88}, 00900 {-93,-105,85},{-97,-117,81},{-106,-119,81},{-127,-121,82}, 00901 {-127,6,93},{-127,27,98},{-85,61,95},{-106,18,96}, 00902 {-110,27,97},{-112,-88,94},{-117,-57,96},{-127,-57,96}, 00903 {-127,-42,95},{-115,-35,100},{-110,-29,102},{-113,-17,100}, 00904 {-122,-16,100},{-127,-26,106},{-121,-19,104},{-115,-20,104}, 00905 {-113,-29,106},{-117,-32,103},{-127,-37,103},{-94,-40,71}, 00906 {-106,-31,91},{-104,-40,91},{-97,-32,71},{-127,-112,88}, 00907 {-121,-111,88},{-115,-105,91},{-115,-95,93},{-127,-100,84}, 00908 {-115,-96,85},{-115,-104,82},{-121,-109,81},{-127,-110,81}, 00909 {-105,28,100},{-103,20,99},{-84,55,97},{-92,54,99}, 00910 {-73,51,99},{-55,45,89},{-52,37,88},{-53,25,87}, 00911 {-66,13,92},{-79,8,95},{-98,14,100},{-104,38,100}, 00912 {-100,48,100},{-97,46,97},{-102,38,97},{-96,16,97}, 00913 {-79,11,93},{-68,15,90},{-57,27,86},{-56,36,86}, 00914 {-59,43,87},{-74,50,96},{-91,51,98},{-84,52,96}, 00915 {-101,22,96},{-102,29,96},{-113,59,78},{-102,85,79}, 00916 {-84,88,76},{-65,71,71},{-40,58,63},{-25,52,59}, 00917 {-28,21,48},{-50,0,53},{-71,-12,60},{-127,115,37}, 00918 {-127,126,-10},{-127,-25,-86},{-127,-59,24},{-127,-125,59}, 00919 {-127,-103,44},{-127,-73,41},{-127,-62,36},{-18,30,7}, 00920 {-17,41,-6},{-28,34,-56},{-68,56,-90},{-33,-6,9}, 00921 {-51,-16,-21},{-45,-1,-55},{-84,7,-85},{-97,-45,52}, 00922 {-104,-53,33},{-90,-91,49},{-95,-64,50},{-85,-117,51}, 00923 {-109,-97,47},{-111,-69,46},{-106,-121,56},{-99,-36,55}, 00924 {-100,-29,60},{-101,-22,64},{-100,-50,21},{-89,-40,-34}, 00925 {-83,-19,-69},{-69,111,-49},{-69,119,-9},{-69,109,30}, 00926 {-68,67,55},{-34,52,43},{-46,58,36},{-45,90,7}, 00927 {-25,72,16},{-25,79,-15},{-45,96,-25},{-45,87,-57}, 00928 {-25,69,-46},{-48,42,-75},{-65,3,-70},{-22,42,-26}, 00929 {-75,-22,19},{-72,-25,-27},{-13,52,-30},{-28,-18,-16}, 00930 {6,-13,-42},{37,7,-55},{46,41,-54},{31,65,-54}, 00931 {4,61,-40},{3,53,-37},{25,56,-50},{35,37,-52}, 00932 {28,10,-52},{5,-5,-39},{-21,-9,-17},{-9,46,-28}, 00933 {-6,39,-37},{-14,-3,-27},{6,0,-47},{25,12,-57}, 00934 {31,32,-57},{23,46,-56},{4,44,-46},{-19,37,-27}, 00935 {-20,22,-35},{-30,12,-35},{-22,11,-35},{-19,2,-35}, 00936 {-23,-2,-35},{-34,0,-9},{-35,-3,-22},{-35,5,-24}, 00937 {-25,26,-27},{-13,31,-34},{-13,30,-41},{-23,-2,-41}, 00938 {-18,2,-41},{-21,10,-41},{-29,12,-41},{-19,22,-41}, 00939 {6,42,-53},{25,44,-62},{34,31,-63},{28,11,-62}, 00940 {7,0,-54},{-14,-2,-34},{-5,37,-44},{-13,14,-42}, 00941 {-7,8,-43},{1,16,-47},{-4,22,-45},{3,30,-48}, 00942 {8,24,-49},{15,27,-50},{12,35,-50},{4,56,-62}, 00943 {33,60,-70},{48,38,-64},{41,7,-68},{6,-11,-63}, 00944 {-26,-16,-42},{-17,49,-49}, 00945 }; 00946 00947 static signed char monkeyf[250][4]= { 00948 {27,4,5,26}, {25,4,5,24}, {3,6,5,4}, {1,6,5,2}, {5,6,7,4}, 00949 {3,6,7,2}, {5,8,7,6}, {3,8,7,4}, {7,8,9,6}, 00950 {5,8,9,4}, {7,10,9,8}, {5,10,9,6}, {9,10,11,8}, 00951 {7,10,11,6}, {9,12,11,10}, {7,12,11,8}, {11,6,13,12}, 00952 {5,4,13,12}, {3,-2,13,12}, {-3,-4,13,12}, {-5,-10,13,12}, 00953 {-11,-12,14,12}, {-13,-18,14,13}, {-19,4,5,13}, {10,12,4,4}, 00954 {10,11,9,9}, {8,7,9,9}, {7,5,6,6}, {6,3,4,4}, 00955 {5,1,2,2}, {4,-1,0,0}, {3,-3,-2,-2}, {22,67,68,23}, 00956 {20,65,66,21}, {18,63,64,19}, {16,61,62,17}, {14,59,60,15}, 00957 {12,19,48,57}, {18,19,48,47}, {18,19,48,47}, {18,19,48,47}, 00958 {18,19,48,47}, {18,19,48,47}, {18,19,48,47}, {18,19,48,47}, 00959 {18,19,48,47}, {18,-9,-8,47}, {18,27,45,46}, {26,55,43,44}, 00960 {24,41,42,54}, {22,39,40,23}, {20,37,38,21}, {18,35,36,19}, 00961 {16,33,34,17}, {14,31,32,15}, {12,39,30,13}, {11,48,45,38}, 00962 {8,36,-19,9}, {8,-20,44,47}, {42,45,46,43}, {18,19,40,39}, 00963 {16,17,38,37}, {14,15,36,35}, {32,44,43,33}, {12,33,32,42}, 00964 {19,44,43,42}, {40,41,42,-27}, {8,9,39,-28}, {15,43,42,16}, 00965 {13,43,42,14}, {11,43,42,12}, {9,-30,42,10}, {37,12,38,-32}, 00966 {-33,37,45,46}, {-33,40,41,39}, {38,40,41,37}, {36,40,41,35}, 00967 {34,40,41,33}, {36,39,38,37}, {35,40,39,38}, {1,2,14,21}, 00968 {1,2,40,13}, {1,2,40,39}, {1,24,12,39}, {-34,36,38,11}, 00969 {35,38,36,37}, {-37,8,35,37}, {-11,-12,-45,40}, {-11,-12,39,38}, 00970 {-11,-12,37,36}, {-11,-12,35,34}, {33,34,40,41}, {33,34,38,39}, 00971 {33,34,36,37}, {33,-52,34,35}, {33,37,36,34}, {33,35,34,34}, 00972 {8,7,37,36}, {-32,7,35,46}, {-34,-33,45,46}, {4,-33,43,34}, 00973 {-34,-33,41,42}, {-34,-33,39,40}, {-34,-33,37,38}, {-34,-33,35,36}, 00974 {-34,-33,33,34}, {-34,-33,31,32}, {-34,-4,28,30}, {-5,-34,28,27}, 00975 {-35,-44,36,27}, {26,35,36,45}, {24,25,44,45}, {25,23,44,42}, 00976 {25,24,41,40}, {25,24,39,38}, {25,24,37,36}, {25,24,35,34}, 00977 {25,24,33,32}, {25,24,31,30}, {15,24,29,38}, {25,24,27,26}, 00978 {23,12,37,26}, {11,12,35,36}, {-86,-59,36,-80}, {-60,-61,36,35}, 00979 {-62,-63,36,35}, {-64,-65,36,35}, {-66,-67,36,35}, {-68,-69,36,35}, 00980 {-70,-71,36,35}, {-72,-73,36,35}, {-74,-75,36,35}, {42,43,53,58}, 00981 {40,41,57,56}, {38,39,55,57}, {-81,-80,37,56}, {-83,-82,55,52}, 00982 {-85,-84,51,49}, {-87,-86,48,49}, {47,50,51,48}, {46,48,51,49}, 00983 {43,46,49,44}, {-92,-91,45,42}, {-23,49,50,-20}, {-94,40,48,-24}, 00984 {-96,-22,48,49}, {-97,48,21,-90}, {-100,36,50,23}, {22,49,48,-100}, 00985 {-101,47,46,22}, {21,45,35,25}, {33,34,44,41}, {13,14,28,24}, 00986 {-107,26,30,-106}, {14,46,45,15}, {14,44,43,-110}, {-111,42,23,-110}, 00987 {6,7,45,46}, {45,44,47,46}, {45,46,47,48}, {47,46,49,48}, 00988 {17,49,47,48}, {17,36,46,48}, {35,36,44,45}, {35,36,40,43}, 00989 {35,36,38,39}, {-4,-3,37,35}, {-123,34,33,1}, {-9,-8,-7,-6}, 00990 {-10,-7,32,-125}, {-127,-11,-126,-126}, {-7,-6,5,31}, {4,5,33,30}, 00991 {4,39,33,32}, {4,35,32,38}, {20,21,39,38}, {4,37,38,5}, 00992 {-11,-10,36,3}, {-11,15,14,35}, {13,16,34,34}, {-13,14,13,13}, 00993 {-3,1,30,29}, {-3,28,29,1}, {-2,31,28,-1}, {12,13,27,30}, 00994 {-2,26,12,12}, {35,29,42,36}, {34,35,36,33}, {32,35,36,31}, 00995 {30,35,36,29}, {28,35,36,27}, {26,35,36,25}, {34,39,38,35}, 00996 {32,39,38,33}, {30,39,38,31}, {28,39,38,29}, {26,39,38,27}, 00997 {25,31,32,38}, {-18,-17,45,44}, {-18,17,28,44}, {-24,-20,42,-23}, 00998 {11,35,27,14}, {25,28,39,41}, {37,41,40,38}, {34,40,36,35}, 00999 {32,40,39,33}, {30,39,31,40}, {21,29,39,22}, {-31,37,28,4}, 01000 {-32,33,35,36}, {32,33,34,34}, {18,35,36,48}, {34,25,40,35}, 01001 {24,25,38,39}, {24,25,36,37}, {24,25,34,35}, {24,25,32,33}, 01002 {24,13,41,31}, {17,11,41,35}, {15,16,34,35}, {13,14,34,35}, 01003 {11,12,34,35}, {9,10,34,35}, {7,8,34,35}, {26,25,37,36}, 01004 {35,36,37,38}, {37,36,39,38}, {37,38,39,40}, {25,31,36,39}, 01005 {18,34,35,30}, {17,22,30,33}, {19,29,21,20}, {16,26,29,17}, 01006 {24,29,28,25}, {22,31,28,23}, {20,31,30,21}, {18,31,30,19}, 01007 {16,30,17,17}, {-21,-22,35,34}, {-21,-22,33,32}, {-21,-22,31,30}, 01008 {-21,-22,29,28}, {-21,-22,27,26}, {-28,-22,25,31}, {24,28,29,30}, 01009 {23,24,26,27}, {23,24,25,25}, {-69,-35,-32,27}, {-70,26,25,-66}, 01010 {-68,-67,24,-33}, 01011 }; 01012 // ------------------------------- end copied code 01013 01014 01015 #define PRIM_PLANE 0 01016 #define PRIM_CUBE 1 01017 #define PRIM_CIRCLE 4 01018 #define PRIM_CYLINDER 5 01019 #define PRIM_CONE 7 01020 #define PRIM_GRID 10 01021 #define PRIM_UVSPHERE 11 01022 #define PRIM_ICOSPHERE 12 01023 #define PRIM_MONKEY 13 01024 01025 static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int seg, 01026 int subdiv, float dia, float depth, int ext, int fill) 01027 { 01028 /* 01029 * type - for the type of shape 01030 * dia - the radius for cone,sphere cylinder etc. 01031 * depth - 01032 * ext - extrude 01033 * fill - end capping, and option to fill in circle 01034 * cent[3] - center of the data. 01035 * */ 01036 EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); 01037 EditVert *eve, *v1=NULL, *v2, *v3, *v4=NULL, *vtop, *vdown; 01038 float phi, phid, vec[3]; 01039 float q[4], cmat[3][3], nor[3]= {0.0, 0.0, 0.0}; 01040 short a, b; 01041 01042 EM_clear_flag_all(em, SELECT); 01043 01044 phid= 2.0f*(float)M_PI/tot; 01045 phi= .25f*(float)M_PI; 01046 01047 switch(type) { 01048 case PRIM_GRID: /* grid */ 01049 /* clear flags */ 01050 eve= em->verts.first; 01051 while(eve) { 01052 eve->f= 0; 01053 eve= eve->next; 01054 } 01055 01056 /* one segment first: the X axis */ 01057 phi = (2*dia)/(float)(tot-1); 01058 phid = (2*dia)/(float)(seg-1); 01059 for(a=tot-1;a>=0;a--) { 01060 vec[0] = (phi*a) - dia; 01061 vec[1]= - dia; 01062 vec[2]= 0.0f; 01063 eve= addvertlist(em, vec, NULL); 01064 eve->f= 1+2+4; 01065 if(a < tot -1) addedgelist(em, eve->prev, eve, NULL); 01066 } 01067 /* extrude and translate */ 01068 vec[0]= vec[2]= 0.0; 01069 vec[1]= phid; 01070 01071 for(a=0;a<seg-1;a++) { 01072 extrudeflag_vert(obedit, em, 2, nor, 0); // nor unused 01073 translateflag(em, 2, vec); 01074 } 01075 01076 /* and now do imat */ 01077 eve= em->verts.first; 01078 while(eve) { 01079 if(eve->f & SELECT) { 01080 mul_m4_v3(mat,eve->co); 01081 } 01082 eve= eve->next; 01083 } 01084 recalc_editnormals(em); 01085 break; 01086 01087 case PRIM_UVSPHERE: /* UVsphere */ 01088 01089 /* clear all flags */ 01090 eve= em->verts.first; 01091 while(eve) { 01092 eve->f= 0; 01093 eve= eve->next; 01094 } 01095 01096 /* one segment first */ 01097 phi= 0; 01098 phid/=2; 01099 for(a=0; a<=tot; a++) { 01100 vec[0]= dia*sinf(phi); 01101 vec[1]= 0.0; 01102 vec[2]= dia*cosf(phi); 01103 eve= addvertlist(em, vec, NULL); 01104 eve->f= 1+2+4; 01105 if(a==0) v1= eve; 01106 else addedgelist(em, eve, eve->prev, NULL); 01107 phi+= phid; 01108 } 01109 01110 /* extrude and rotate */ 01111 phi= M_PI/seg; 01112 q[0]= cos(phi); 01113 q[3]= sin(phi); 01114 q[1]=q[2]= 0; 01115 quat_to_mat3( cmat,q); 01116 01117 for(a=0; a<seg; a++) { 01118 extrudeflag_vert(obedit, em, 2, nor, 0); // nor unused 01119 rotateflag(em, 2, v1->co, cmat); 01120 } 01121 01122 removedoublesflag(em, 4, 0, 0.0001); 01123 01124 /* and now do imat */ 01125 eve= em->verts.first; 01126 while(eve) { 01127 if(eve->f & SELECT) { 01128 mul_m4_v3(mat,eve->co); 01129 } 01130 eve= eve->next; 01131 } 01132 recalc_editnormals(em); 01133 break; 01134 case PRIM_ICOSPHERE: /* Icosphere */ 01135 { 01136 EditVert *eva[12]; 01137 EditEdge *eed; 01138 01139 /* clear all flags */ 01140 eve= em->verts.first; 01141 while(eve) { 01142 eve->f= 0; 01143 eve= eve->next; 01144 } 01145 dia/=200; 01146 for(a=0;a<12;a++) { 01147 vec[0]= dia*icovert[a][0]; 01148 vec[1]= dia*icovert[a][1]; 01149 vec[2]= dia*icovert[a][2]; 01150 eva[a]= addvertlist(em, vec, NULL); 01151 eva[a]->f= 1+2; 01152 } 01153 for(a=0;a<20;a++) { 01154 EditFace *evtemp; 01155 v1= eva[ icoface[a][0] ]; 01156 v2= eva[ icoface[a][1] ]; 01157 v3= eva[ icoface[a][2] ]; 01158 evtemp = addfacelist(em, v1, v2, v3, 0, NULL, NULL); 01159 evtemp->e1->f = 1+2; 01160 evtemp->e2->f = 1+2; 01161 evtemp->e3->f = 1+2; 01162 } 01163 01164 dia*=200; 01165 for(a=1; a<subdiv; a++) esubdivideflag(obedit, em, 2, dia, 0, B_SPHERE,1, SUBDIV_CORNER_PATH, 0); 01166 /* and now do imat */ 01167 eve= em->verts.first; 01168 while(eve) { 01169 if(eve->f & 2) { 01170 mul_m4_v3(mat,eve->co); 01171 } 01172 eve= eve->next; 01173 } 01174 01175 // Clear the flag 2 from the edges 01176 for(eed=em->edges.first;eed;eed=eed->next){ 01177 if(eed->f & 2){ 01178 eed->f &= !2; 01179 } 01180 } 01181 } 01182 break; 01183 case PRIM_MONKEY: /* Monkey */ 01184 { 01185 //extern int monkeyo, monkeynv, monkeynf; 01186 //extern signed char monkeyf[][4]; 01187 //extern signed char monkeyv[][3]; 01188 EditVert **tv= MEM_mallocN(sizeof(*tv)*monkeynv*2, "tv"); 01189 int i; 01190 01191 for (i=0; i<monkeynv; i++) { 01192 float v[3]; 01193 v[0]= (monkeyv[i][0]+127)/128.0, v[1]= monkeyv[i][1]/128.0, v[2]= monkeyv[i][2]/128.0; 01194 tv[i]= addvertlist(em, v, NULL); 01195 tv[i]->f |= SELECT; 01196 tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(em, v, NULL); 01197 tv[monkeynv+i]->f |= SELECT; 01198 } 01199 for (i=0; i<monkeynf; i++) { 01200 addfacelist(em, tv[monkeyf[i][0]+i-monkeyo], tv[monkeyf[i][1]+i-monkeyo], tv[monkeyf[i][2]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeyf[i][3]+i-monkeyo]:NULL, NULL, NULL); 01201 addfacelist(em, tv[monkeynv+monkeyf[i][2]+i-monkeyo], tv[monkeynv+monkeyf[i][1]+i-monkeyo], tv[monkeynv+monkeyf[i][0]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeynv+monkeyf[i][3]+i-monkeyo]:NULL, NULL, NULL); 01202 } 01203 01204 MEM_freeN(tv); 01205 01206 /* and now do imat */ 01207 for(eve= em->verts.first; eve; eve= eve->next) { 01208 if(eve->f & SELECT) { 01209 mul_m4_v3(mat,eve->co); 01210 } 01211 } 01212 recalc_editnormals(em); 01213 } 01214 break; 01215 default: /* all types except grid, sphere... */ 01216 if(type==PRIM_CONE); 01217 else if(ext==0) 01218 depth= 0.0f; 01219 01220 /* first vertex at 0° for circular objects */ 01221 if( ELEM3(type, PRIM_CIRCLE,PRIM_CYLINDER,PRIM_CONE) ) 01222 phi = 0.0f; 01223 01224 vtop= vdown= v1= v2= 0; 01225 for(b=0; b<=ext; b++) { 01226 for(a=0; a<tot; a++) { 01227 01228 vec[0]= dia*sinf(phi); 01229 vec[1]= dia*cosf(phi); 01230 vec[2]= b?depth:-depth; 01231 01232 mul_m4_v3(mat, vec); 01233 eve= addvertlist(em, vec, NULL); 01234 eve->f= SELECT; 01235 if(a==0) { 01236 if(b==0) v1= eve; 01237 else v2= eve; 01238 } 01239 phi+=phid; 01240 } 01241 } 01242 01243 /* center vertices */ 01244 /* type PRIM_CONE can only have 1 one side filled 01245 * if the cone has no capping, dont add vtop */ 01246 if(type == PRIM_CONE || (fill && !ELEM(type, PRIM_PLANE, PRIM_CUBE))) { 01247 vec[0]= vec[1]= 0.0f; 01248 vec[2]= type==PRIM_CONE ? depth : -depth; 01249 mul_m4_v3(mat, vec); 01250 vdown= addvertlist(em, vec, NULL); 01251 if((ext || type==PRIM_CONE) && fill) { 01252 vec[0]= vec[1]= 0.0f; 01253 vec[2]= type==PRIM_CONE ? -depth : depth; 01254 mul_m4_v3(mat,vec); 01255 vtop= addvertlist(em, vec, NULL); 01256 } 01257 } else { 01258 vdown= v1; 01259 vtop= v2; 01260 } 01261 if(vtop) vtop->f= SELECT; 01262 if(vdown) vdown->f= SELECT; 01263 01264 /* top and bottom face */ 01265 if(fill || type==PRIM_CONE) { 01266 if(tot==4 && ELEM(type, PRIM_PLANE, PRIM_CUBE)) { 01267 v3= v1->next->next; 01268 if(ext) v4= v2->next->next; 01269 01270 addfacelist(em, v3, v1->next, v1, v3->next, NULL, NULL); 01271 if(ext) addfacelist(em, v2, v2->next, v4, v4->next, NULL, NULL); 01272 01273 } 01274 else { 01275 v3= v1; 01276 v4= v2; 01277 for(a=1; a<tot; a++) { 01278 addfacelist(em, vdown, v3, v3->next, 0, NULL, NULL); 01279 v3= v3->next; 01280 if(ext && fill) { 01281 addfacelist(em, vtop, v4, v4->next, 0, NULL, NULL); 01282 v4= v4->next; 01283 } 01284 } 01285 if(!ELEM(type, PRIM_PLANE, PRIM_CUBE)) { 01286 addfacelist(em, vdown, v3, v1, 0, NULL, NULL); 01287 if(ext) addfacelist(em, vtop, v4, v2, 0, NULL, NULL); 01288 } 01289 } 01290 } 01291 else if(type==PRIM_CIRCLE) { /* we need edges for a circle */ 01292 v3= v1; 01293 for(a=1;a<tot;a++) { 01294 addedgelist(em, v3, v3->next, NULL); 01295 v3= v3->next; 01296 } 01297 addedgelist(em, v3, v1, NULL); 01298 } 01299 /* side faces */ 01300 if(ext) { 01301 v3= v1; 01302 v4= v2; 01303 for(a=1; a<tot; a++) { 01304 addfacelist(em, v3, v3->next, v4->next, v4, NULL, NULL); 01305 v3= v3->next; 01306 v4= v4->next; 01307 } 01308 addfacelist(em, v3, v1, v2, v4, NULL, NULL); 01309 } 01310 else if(fill && type==PRIM_CONE) { 01311 /* add the bottom flat area of the cone 01312 * if capping is disabled dont bother */ 01313 v3= v1; 01314 for(a=1; a<tot; a++) { 01315 addfacelist(em, vtop, v3->next, v3, 0, NULL, NULL); 01316 v3= v3->next; 01317 } 01318 addfacelist(em, vtop, v1, v3, 0, NULL, NULL); 01319 } 01320 } 01321 01322 EM_stats_update(em); 01323 /* simple selection flush OK, based on fact it's a single model */ 01324 EM_select_flush(em); /* flushes vertex -> edge -> face selection */ 01325 01326 if(!ELEM5(type, PRIM_GRID, PRIM_PLANE, PRIM_ICOSPHERE, PRIM_UVSPHERE, PRIM_MONKEY)) 01327 EM_recalc_normal_direction(em, FALSE, TRUE); /* otherwise monkey has eyes in wrong direction */ 01328 01329 BKE_mesh_end_editmesh(obedit->data, em); 01330 } 01331 01332 /* ********* add primitive operators ************* */ 01333 01334 static const char *get_mesh_defname(int type) 01335 { 01336 switch (type) { 01337 case PRIM_PLANE: return "Plane"; 01338 case PRIM_CUBE: return "Cube"; 01339 case PRIM_CIRCLE: return "Circle"; 01340 case PRIM_CYLINDER: return "Cylinder"; 01341 case PRIM_CONE: return "Cone"; 01342 case PRIM_GRID: return "Grid"; 01343 case PRIM_UVSPHERE: return "Sphere"; 01344 case PRIM_ICOSPHERE: return "Icosphere"; 01345 case PRIM_MONKEY: return "Monkey"; 01346 default: 01347 return "Mesh"; 01348 } 01349 } 01350 01351 static void make_prim_ext(bContext *C, float *loc, float *rot, int enter_editmode, unsigned int layer, 01352 int type, int tot, int seg, 01353 int subdiv, float dia, float depth, int ext, int fill) 01354 { 01355 Object *obedit= CTX_data_edit_object(C); 01356 int newob = 0; 01357 float mat[4][4]; 01358 float scale; 01359 01360 if(obedit==NULL || obedit->type!=OB_MESH) { 01361 obedit= ED_object_add_type(C, OB_MESH, loc, rot, FALSE, layer); 01362 01363 rename_id((ID *)obedit, get_mesh_defname(type)); 01364 rename_id((ID *)obedit->data, get_mesh_defname(type)); 01365 01366 /* create editmode */ 01367 ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER); /* rare cases the active layer is messed up */ 01368 newob = 1; 01369 } 01370 else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); 01371 01372 scale= ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); 01373 01374 dia *= scale; 01375 depth *= scale * 0.5f; 01376 01377 make_prim(obedit, type, mat, tot, seg, subdiv, dia, depth, ext, fill); 01378 01379 DAG_id_tag_update(obedit->data, 0); 01380 WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); 01381 01382 01383 /* userdef */ 01384 if (newob && !enter_editmode) { 01385 ED_object_exit_editmode(C, EM_FREEDATA); /* adding EM_DO_UNDO messes up operator redo */ 01386 } 01387 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); 01388 } 01389 01390 static int add_primitive_plane_exec(bContext *C, wmOperator *op) 01391 { 01392 int enter_editmode; 01393 unsigned int layer; 01394 float loc[3], rot[3]; 01395 01396 if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) 01397 return OPERATOR_CANCELLED; 01398 01399 /* sqrt(2.0f) - plane (diameter of 1.41 makes it unit size) */ 01400 make_prim_ext(C, loc, rot, enter_editmode, layer, 01401 PRIM_PLANE, 4, 0, 0, sqrt(2.0f), 0.0f, 0, 1); 01402 return OPERATOR_FINISHED; 01403 } 01404 01405 void MESH_OT_primitive_plane_add(wmOperatorType *ot) 01406 { 01407 /* identifiers */ 01408 ot->name= "Add Plane"; 01409 ot->description= "Construct a filled planar mesh with 4 vertices"; 01410 ot->idname= "MESH_OT_primitive_plane_add"; 01411 01412 /* api callbacks */ 01413 ot->invoke= ED_object_add_generic_invoke; 01414 ot->exec= add_primitive_plane_exec; 01415 ot->poll= ED_operator_scene_editable; 01416 01417 /* flags */ 01418 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01419 01420 ED_object_add_generic_props(ot, TRUE); 01421 } 01422 01423 static int add_primitive_cube_exec(bContext *C, wmOperator *op) 01424 { 01425 int enter_editmode; 01426 unsigned int layer; 01427 float loc[3], rot[3]; 01428 01429 if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) 01430 return OPERATOR_CANCELLED; 01431 01432 /* sqrt(2.0f) - plane (diameter of 1.41 makes it unit size) */ 01433 make_prim_ext(C, loc, rot, enter_editmode, layer, 01434 PRIM_CUBE, 4, 0, 0, sqrt(2.0f), 2.0f, 1, 1); 01435 return OPERATOR_FINISHED; 01436 } 01437 01438 void MESH_OT_primitive_cube_add(wmOperatorType *ot) 01439 { 01440 /* identifiers */ 01441 ot->name= "Add Cube"; 01442 ot->description= "Construct a cube mesh"; 01443 ot->idname= "MESH_OT_primitive_cube_add"; 01444 01445 /* api callbacks */ 01446 ot->invoke= ED_object_add_generic_invoke; 01447 ot->exec= add_primitive_cube_exec; 01448 ot->poll= ED_operator_scene_editable; 01449 01450 /* flags */ 01451 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01452 01453 ED_object_add_generic_props(ot, TRUE); 01454 } 01455 01456 static int add_primitive_circle_exec(bContext *C, wmOperator *op) 01457 { 01458 int enter_editmode; 01459 unsigned int layer; 01460 float loc[3], rot[3]; 01461 01462 if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) 01463 return OPERATOR_CANCELLED; 01464 01465 make_prim_ext(C, loc, rot, enter_editmode, layer, 01466 PRIM_CIRCLE, RNA_int_get(op->ptr, "vertices"), 0, 0, 01467 RNA_float_get(op->ptr,"radius"), 0.0f, 0, 01468 RNA_boolean_get(op->ptr, "fill")); 01469 01470 return OPERATOR_FINISHED; 01471 } 01472 01473 void MESH_OT_primitive_circle_add(wmOperatorType *ot) 01474 { 01475 /* identifiers */ 01476 ot->name= "Add Circle"; 01477 ot->description= "Construct a circle mesh"; 01478 ot->idname= "MESH_OT_primitive_circle_add"; 01479 01480 /* api callbacks */ 01481 ot->invoke= ED_object_add_generic_invoke; 01482 ot->exec= add_primitive_circle_exec; 01483 ot->poll= ED_operator_scene_editable; 01484 01485 /* flags */ 01486 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01487 01488 /* props */ 01489 RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 3, 500); 01490 RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); 01491 RNA_def_boolean(ot->srna, "fill", 0, "Fill", ""); 01492 01493 ED_object_add_generic_props(ot, TRUE); 01494 } 01495 01496 static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) 01497 { 01498 int enter_editmode; 01499 unsigned int layer; 01500 float loc[3], rot[3]; 01501 01502 if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) 01503 return OPERATOR_CANCELLED; 01504 01505 make_prim_ext(C, loc, rot, enter_editmode, layer, 01506 PRIM_CYLINDER, RNA_int_get(op->ptr, "vertices"), 0, 0, 01507 RNA_float_get(op->ptr,"radius"), 01508 RNA_float_get(op->ptr, "depth"), 1, 01509 RNA_boolean_get(op->ptr, "cap_ends")); 01510 01511 return OPERATOR_FINISHED; 01512 } 01513 01514 void MESH_OT_primitive_cylinder_add(wmOperatorType *ot) 01515 { 01516 /* identifiers */ 01517 ot->name= "Add Cylinder"; 01518 ot->description= "Construct a cylinder mesh"; 01519 ot->idname= "MESH_OT_primitive_cylinder_add"; 01520 01521 /* api callbacks */ 01522 ot->invoke= ED_object_add_generic_invoke; 01523 ot->exec= add_primitive_cylinder_exec; 01524 ot->poll= ED_operator_scene_editable; 01525 01526 /* flags */ 01527 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01528 01529 /* props */ 01530 RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500); 01531 RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); 01532 RNA_def_float(ot->srna, "depth", 2.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00); 01533 RNA_def_boolean(ot->srna, "cap_ends", 1, "Cap Ends", ""); 01534 01535 ED_object_add_generic_props(ot, TRUE); 01536 } 01537 01538 static int add_primitive_cone_exec(bContext *C, wmOperator *op) 01539 { 01540 int enter_editmode; 01541 unsigned int layer; 01542 float loc[3], rot[3]; 01543 01544 if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) 01545 return OPERATOR_CANCELLED; 01546 01547 make_prim_ext(C, loc, rot, enter_editmode, layer, 01548 PRIM_CONE, RNA_int_get(op->ptr, "vertices"), 0, 0, 01549 RNA_float_get(op->ptr,"radius"), RNA_float_get(op->ptr, "depth"), 01550 0, RNA_boolean_get(op->ptr, "cap_end")); 01551 01552 return OPERATOR_FINISHED; 01553 } 01554 01555 void MESH_OT_primitive_cone_add(wmOperatorType *ot) 01556 { 01557 /* identifiers */ 01558 ot->name= "Add Cone"; 01559 ot->description= "Construct a conic mesh (ends filled)"; 01560 ot->idname= "MESH_OT_primitive_cone_add"; 01561 01562 /* api callbacks */ 01563 ot->invoke= ED_object_add_generic_invoke; 01564 ot->exec= add_primitive_cone_exec; 01565 ot->poll= ED_operator_scene_editable; 01566 01567 /* flags */ 01568 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01569 01570 /* props */ 01571 RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500); 01572 RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00); 01573 RNA_def_float(ot->srna, "depth", 2.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00); 01574 RNA_def_boolean(ot->srna, "cap_end", 1, "Cap End", ""); 01575 01576 ED_object_add_generic_props(ot, TRUE); 01577 } 01578 01579 static int add_primitive_grid_exec(bContext *C, wmOperator *op) 01580 { 01581 int enter_editmode; 01582 unsigned int layer; 01583 float loc[3], rot[3]; 01584 01585 if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) 01586 return OPERATOR_CANCELLED; 01587 01588 make_prim_ext(C, loc, rot, enter_editmode, layer, 01589 PRIM_GRID, RNA_int_get(op->ptr, "x_subdivisions"), 01590 RNA_int_get(op->ptr, "y_subdivisions"), 0, 01591 RNA_float_get(op->ptr,"size"), 0.0f, 0, 1); 01592 01593 return OPERATOR_FINISHED; 01594 } 01595 01596 void MESH_OT_primitive_grid_add(wmOperatorType *ot) 01597 { 01598 /* identifiers */ 01599 ot->name= "Add Grid"; 01600 ot->description= "Construct a grid mesh"; 01601 ot->idname= "MESH_OT_primitive_grid_add"; 01602 01603 /* api callbacks */ 01604 ot->invoke= ED_object_add_generic_invoke; 01605 ot->exec= add_primitive_grid_exec; 01606 ot->poll= ED_operator_scene_editable; 01607 01608 /* flags */ 01609 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01610 01611 /* props */ 01612 RNA_def_int(ot->srna, "x_subdivisions", 10, INT_MIN, INT_MAX, "X Subdivisions", "", 3, 1000); 01613 RNA_def_int(ot->srna, "y_subdivisions", 10, INT_MIN, INT_MAX, "Y Subdivisions", "", 3, 1000); 01614 RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, FLT_MAX); 01615 01616 ED_object_add_generic_props(ot, TRUE); 01617 } 01618 01619 static int add_primitive_monkey_exec(bContext *C, wmOperator *op) 01620 { 01621 int enter_editmode; 01622 unsigned int layer; 01623 float loc[3], rot[3]; 01624 01625 if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) 01626 return OPERATOR_CANCELLED; 01627 01628 make_prim_ext(C, loc, rot, enter_editmode, layer, 01629 PRIM_MONKEY, 0, 0, 2, 0.0f, 0.0f, 0, 0); 01630 01631 return OPERATOR_FINISHED; 01632 } 01633 01634 void MESH_OT_primitive_monkey_add(wmOperatorType *ot) 01635 { 01636 /* identifiers */ 01637 ot->name= "Add Monkey"; 01638 ot->description= "Construct a Suzanne mesh"; 01639 ot->idname= "MESH_OT_primitive_monkey_add"; 01640 01641 /* api callbacks */ 01642 ot->invoke= ED_object_add_generic_invoke; 01643 ot->exec= add_primitive_monkey_exec; 01644 ot->poll= ED_operator_scene_editable; 01645 01646 /* flags */ 01647 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01648 01649 ED_object_add_generic_props(ot, TRUE); 01650 } 01651 01652 static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) 01653 { 01654 int enter_editmode; 01655 unsigned int layer; 01656 float loc[3], rot[3]; 01657 01658 if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) 01659 return OPERATOR_CANCELLED; 01660 01661 make_prim_ext(C, loc, rot, enter_editmode, layer, 01662 PRIM_UVSPHERE, RNA_int_get(op->ptr, "ring_count"), 01663 RNA_int_get(op->ptr, "segments"), 0, 01664 RNA_float_get(op->ptr,"size"), 0.0f, 0, 0); 01665 01666 return OPERATOR_FINISHED; 01667 } 01668 01669 void MESH_OT_primitive_uv_sphere_add(wmOperatorType *ot) 01670 { 01671 /* identifiers */ 01672 ot->name= "Add UV Sphere"; 01673 ot->description= "Construct a UV sphere mesh"; 01674 ot->idname= "MESH_OT_primitive_uv_sphere_add"; 01675 01676 /* api callbacks */ 01677 ot->invoke= ED_object_add_generic_invoke; 01678 ot->exec= add_primitive_uvsphere_exec; 01679 ot->poll= ED_operator_scene_editable; 01680 01681 /* flags */ 01682 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01683 01684 /* props */ 01685 RNA_def_int(ot->srna, "segments", 32, INT_MIN, INT_MAX, "Segments", "", 3, 500); 01686 RNA_def_int(ot->srna, "ring_count", 16, INT_MIN, INT_MAX, "Rings", "", 3, 500); 01687 RNA_def_float(ot->srna, "size", 1.0f, 0.0, FLT_MAX, "Size", "", 0.001, 100.00); 01688 01689 ED_object_add_generic_props(ot, TRUE); 01690 } 01691 01692 static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) 01693 { 01694 int enter_editmode; 01695 unsigned int layer; 01696 float loc[3], rot[3]; 01697 01698 if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) 01699 return OPERATOR_CANCELLED; 01700 01701 make_prim_ext(C, loc, rot, enter_editmode, layer, 01702 PRIM_ICOSPHERE, 0, 0, RNA_int_get(op->ptr, "subdivisions"), 01703 RNA_float_get(op->ptr,"size"), 0.0f, 0, 0); 01704 01705 return OPERATOR_FINISHED; 01706 } 01707 01708 void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot) 01709 { 01710 /* identifiers */ 01711 ot->name= "Add Ico Sphere"; 01712 ot->description= "Construct an Icosphere mesh"; 01713 ot->idname= "MESH_OT_primitive_ico_sphere_add"; 01714 01715 /* api callbacks */ 01716 ot->invoke= ED_object_add_generic_invoke; 01717 ot->exec= add_primitive_icosphere_exec; 01718 ot->poll= ED_operator_scene_editable; 01719 01720 /* flags */ 01721 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 01722 01723 /* props */ 01724 RNA_def_int(ot->srna, "subdivisions", 2, 0, INT_MAX, "Subdivisions", "", 0, 8); 01725 RNA_def_float(ot->srna, "size", 1.0f, 0.0f, FLT_MAX, "Size", "", 0.001f, 100.00); 01726 01727 ED_object_add_generic_props(ot, TRUE); 01728 } 01729 01730 /****************** add duplicate operator ***************/ 01731 01732 static int mesh_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) 01733 { 01734 Object *ob= CTX_data_edit_object(C); 01735 EditMesh *em= BKE_mesh_get_editmesh(ob->data); 01736 01737 adduplicateflag(em, SELECT); 01738 01739 BKE_mesh_end_editmesh(ob->data, em); 01740 01741 DAG_id_tag_update(ob->data, 0); 01742 WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); 01743 01744 return OPERATOR_FINISHED; 01745 } 01746 01747 static int mesh_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) 01748 { 01749 WM_cursor_wait(1); 01750 mesh_duplicate_exec(C, op); 01751 WM_cursor_wait(0); 01752 01753 return OPERATOR_FINISHED; 01754 } 01755 01756 void MESH_OT_duplicate(wmOperatorType *ot) 01757 { 01758 /* identifiers */ 01759 ot->name= "Duplicate Mesh"; 01760 ot->description= "Duplicate selected vertices, edges or faces"; 01761 ot->idname= "MESH_OT_duplicate"; 01762 01763 /* api callbacks */ 01764 ot->invoke= mesh_duplicate_invoke; 01765 ot->exec= mesh_duplicate_exec; 01766 01767 ot->poll= ED_operator_editmesh; 01768 01769 /* to give to transform */ 01770 RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", ""); 01771 } 01772