|
@@ -1144,23 +1144,25 @@ int OPINV_Extrude(laOperator *a, laEvent *e){
|
|
|
if(!a->This || !a->This->EndInstance){ return 0; }
|
|
|
laCanvasExtra* ex=a->This->EndInstance; tnsCamera*c=ex->ViewingCamera; laUiItem* ui=ex->ParentUi;
|
|
|
tnsObject*root=ui?ui->PP.EndInstance:0; if(!root) return 0;
|
|
|
- tnsMeshObject* mo=root->Active; if(mo->Base.Type!=TNS_OBJECT_MESH || mo->Mode!=TNS_MESH_EDIT_MODE) return 0;
|
|
|
+ tnsMeshObject* mo=root->Active; tnsShapeObject* so=mo; if(!mo) return 0;
|
|
|
|
|
|
- if(!tnsMMeshAnySelected(mo)) return LA_FINISHED;
|
|
|
-
|
|
|
- MExtrudeExtra* ee=la_InitExtrude(mo);
|
|
|
-
|
|
|
- la_ExtrudeMakeDuplication(ee);
|
|
|
-
|
|
|
- if(strSame(strGetArgumentString(a->ExtraInstructionsP,"duplicate_only"), "true")){
|
|
|
+ if(mo->Base.Type==TNS_OBJECT_MESH && mo->Mode==TNS_MESH_EDIT_MODE){
|
|
|
+ if(!tnsMMeshAnySelected(mo)) return LA_FINISHED;
|
|
|
+ MExtrudeExtra* ee=la_InitExtrude(mo);
|
|
|
+ la_ExtrudeMakeDuplication(ee);
|
|
|
+ if(strSame(strGetArgumentString(a->ExtraInstructionsP,"duplicate_only"), "true")){
|
|
|
+ la_FinishExtrude(ee, 1);
|
|
|
+ if(la_InitTransform(a, e, LA_TRANSFORM_MODE_GRAB,0,0)) return LA_RUNNING; return LA_FINISHED;
|
|
|
+ }
|
|
|
+ la_RemoveOriginalFaces(ee);
|
|
|
+ la_ReconnectFaces(ee);
|
|
|
la_FinishExtrude(ee, 1);
|
|
|
- if(la_InitTransform(a, e, LA_TRANSFORM_MODE_GRAB,0,0)) return LA_RUNNING; return LA_FINISHED;
|
|
|
+ }elif(so->Base.Type==TNS_OBJECT_SHAPE && so->Mode==TNS_MESH_EDIT_MODE){
|
|
|
+ int duponly=strSame(strGetArgumentString(a->ExtraInstructionsP,"duplicate_only"), "true");
|
|
|
+ tnsShapeExtrudeSelected(so,duponly);
|
|
|
+ }else{
|
|
|
+ return LA_CANCELED;
|
|
|
}
|
|
|
-
|
|
|
- la_RemoveOriginalFaces(ee);
|
|
|
- la_ReconnectFaces(ee);
|
|
|
-
|
|
|
- la_FinishExtrude(ee, 1);
|
|
|
if(la_InitTransform(a, e, LA_TRANSFORM_MODE_GRAB,0,0)) return LA_RUNNING; return LA_FINISHED;
|
|
|
|
|
|
return LA_FINISHED;
|
|
@@ -1235,6 +1237,15 @@ void la_DeleteFaces(tnsMeshObject* mo, int OnlyFaces){
|
|
|
tnsMVert* mv; while(mv=lstPopPointer(&lv)){ tnsMMeshRemoveVertEdgeFace(mo,mv); }
|
|
|
}
|
|
|
}
|
|
|
+void la_DeletePoints(tnsShapeObject* so, int SplitShape){
|
|
|
+ for(tnsShape* s=so->Shapes.pFirst;s;s=s->Item.pNext){
|
|
|
+ tnsSPoint* NextSP; for(tnsSPoint* sp=s->Points.pFirst;sp;sp=NextSP){ NextSP=sp->Item.pNext;
|
|
|
+ if(!(sp->flags&TNS_MESH_FLAG_SELECTED)) continue;
|
|
|
+ tnsShapeRemovePoint(so,s,sp,SplitShape);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tnsShapeRefreshIndex(so);
|
|
|
+}
|
|
|
int la_DeleteSelectedObjectsRecursive(tnsObject* root){
|
|
|
int any=0; for(laListItemPointer* lip=root->ChildObjects.pFirst;lip;lip=lip->pNext){ if(!lip->p) continue;
|
|
|
tnsObject* o=lip->p; la_DeleteSelectedObjectsRecursive(lip->p);
|
|
@@ -1242,17 +1253,17 @@ int la_DeleteSelectedObjectsRecursive(tnsObject* root){
|
|
|
}
|
|
|
return any;
|
|
|
}
|
|
|
+STRUCTURE(MDeleteData){
|
|
|
+ int _PAD;
|
|
|
+ int Context;
|
|
|
+};
|
|
|
int OPINV_Delete(laOperator *a, laEvent *e){
|
|
|
if(!a->This || !a->This->EndInstance){ return 0; }
|
|
|
laCanvasExtra* ex=a->This->EndInstance; tnsCamera*c=ex->ViewingCamera; laUiItem* ui=ex->ParentUi;
|
|
|
tnsObject*root=ui?ui->PP.EndInstance:0; if(!root) return 0;
|
|
|
- tnsMeshObject* mo=root->Active; if(!mo) return 0;
|
|
|
+ tnsMeshObject* mo=root->Active; tnsShapeObject* so=mo; if(!mo) return 0;
|
|
|
|
|
|
- if(mo->Base.Type!=TNS_OBJECT_MESH || mo->Mode!=TNS_MESH_EDIT_MODE){
|
|
|
- if(la_DeleteSelectedObjectsRecursive(root)){
|
|
|
- laRecordInstanceDifferences(T->World, "tns_world"); laPushDifferences("Deleted objects", TNS_HINT_TRANSFORM); laNotifyUsers("tns.world");
|
|
|
- }
|
|
|
- }else{
|
|
|
+ if(mo->Base.Type==TNS_OBJECT_MESH && mo->Mode==TNS_MESH_EDIT_MODE){
|
|
|
if(!tnsMMeshAnySelected(mo)) return LA_FINISHED;
|
|
|
if(strSame(strGetArgumentString(a->ExtraInstructionsP, "mode"),"vertices")){
|
|
|
la_DeleteVertices(mo);
|
|
@@ -1263,23 +1274,43 @@ int OPINV_Delete(laOperator *a, laEvent *e){
|
|
|
}elif(strSame(strGetArgumentString(a->ExtraInstructionsP, "mode"),"only_faces")){
|
|
|
la_DeleteFaces(mo,1);
|
|
|
}else{
|
|
|
- laEnableOperatorPanel(a,a->This,e->x,e->y,200,200,0,0,0,0,0,0,0,0,e);
|
|
|
- return LA_RUNNING;
|
|
|
+ MDeleteData* md=memAcquire(sizeof(MDeleteData)); a->CustomData=md; md->Context=TNS_OBJECT_MESH;
|
|
|
+ laEnableOperatorPanel(a,a->This,e->x,e->y,200,200,0,0,0,0,0,0,0,0,e); return LA_RUNNING;
|
|
|
}
|
|
|
tnsMMeshDeselectAll(mo);
|
|
|
tnsMMeshRefreshIndex(mo);
|
|
|
tnsInvalidateMeshBatch(mo);
|
|
|
laRecordInstanceDifferences(mo, "tns_mesh_object"); laPushDifferences("Deleted primitives", TNS_HINT_GEOMETRY); laNotifyUsers("tns.world");
|
|
|
+ }if(so->Base.Type==TNS_OBJECT_SHAPE && so->Mode==TNS_MESH_EDIT_MODE){
|
|
|
+ if(!tnsShapeAnySelected(so)) return LA_FINISHED;
|
|
|
+ char* split=strGetArgumentString(a->ExtraInstructionsP, "split");
|
|
|
+ if(split){
|
|
|
+ int SplitShapes=strSame(split,"TRUE"); la_DeletePoints(so,SplitShapes);
|
|
|
+ }else{
|
|
|
+ MDeleteData* md=memAcquire(sizeof(MDeleteData)); a->CustomData=md; md->Context=TNS_OBJECT_SHAPE;
|
|
|
+ laEnableOperatorPanel(a,a->This,e->x,e->y,200,200,0,0,0,0,0,0,0,0,e); return LA_RUNNING;
|
|
|
+ }
|
|
|
+ laRecordInstanceDifferences(so, "tns_shape_object"); laPushDifferences("Deleted points", TNS_HINT_GEOMETRY); laNotifyUsers("tns.world");
|
|
|
+ }else{
|
|
|
+ if(la_DeleteSelectedObjectsRecursive(root)){
|
|
|
+ laRecordInstanceDifferences(T->World, "tns_world"); laPushDifferences("Deleted objects", TNS_HINT_TRANSFORM); laNotifyUsers("tns.world");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return LA_FINISHED;
|
|
|
}
|
|
|
void laui_Delete(laUiList *uil, laPropPack *pp, laPropPack *actinst, laColumn *extracol, int context){
|
|
|
- laColumn* c=laFirstColumn(uil);
|
|
|
- laShowItemFull(uil,c,pp,"_this_M_delete",0,"mode=vertices;text=Vertices",0,0);
|
|
|
- laShowItemFull(uil,c,pp,"_this_M_delete",0,"mode=edges;text=Edges",0,0);
|
|
|
- laShowItemFull(uil,c,pp,"_this_M_delete",0,"mode=faces;text=Faces",0,0);
|
|
|
- laShowItemFull(uil,c,pp,"_this_M_delete",0,"mode=only_faces;text=Only Faces",0,0);
|
|
|
+ laColumn* c=laFirstColumn(uil); laUiItem* b;
|
|
|
+ b=laOnConditionThat(uil,c,laEqual(laPropExpression(actinst,"context"),laIntExpression(TNS_OBJECT_MESH)));{
|
|
|
+ laShowItemFull(uil,c,pp,"_this_M_delete",0,"mode=vertices;text=Vertices",0,0);
|
|
|
+ laShowItemFull(uil,c,pp,"_this_M_delete",0,"mode=edges;text=Edges",0,0);
|
|
|
+ laShowItemFull(uil,c,pp,"_this_M_delete",0,"mode=faces;text=Faces",0,0);
|
|
|
+ laShowItemFull(uil,c,pp,"_this_M_delete",0,"mode=only_faces;text=Only Faces",0,0);
|
|
|
+ }laEndCondition(uil,b);
|
|
|
+ b=laOnConditionThat(uil,c,laEqual(laPropExpression(actinst,"context"),laIntExpression(TNS_OBJECT_SHAPE)));{
|
|
|
+ laShowItemFull(uil,c,pp,"_this_M_delete",0,"split=FALSE;",0,0);
|
|
|
+ laShowItemFull(uil,c,pp,"_this_M_delete",0,"split=TRUE;text=Delet and Split",0,0);
|
|
|
+ }laEndCondition(uil,b);
|
|
|
}
|
|
|
|
|
|
STRUCTURE(MIslandInfo){
|
|
@@ -1396,20 +1427,27 @@ int OPINV_Make(laOperator *a, laEvent *e){
|
|
|
if(!a->This || !a->This->EndInstance){ return 0; }
|
|
|
laCanvasExtra* ex=a->This->EndInstance; tnsCamera*c=ex->ViewingCamera; laUiItem* ui=ex->ParentUi;
|
|
|
tnsObject*root=ui?ui->PP.EndInstance:0; if(!root) return 0;
|
|
|
- tnsMeshObject* mo=root->Active;
|
|
|
+ tnsMeshObject* mo=root->Active; tnsShapeObject*so=mo;
|
|
|
|
|
|
- if(!mo||mo->Base.Type!=TNS_OBJECT_MESH || mo->Mode!=TNS_MESH_EDIT_MODE){ return LA_CANCELED; }
|
|
|
+ if(!mo){ return LA_CANCELED; }
|
|
|
|
|
|
- MMakeData md={0};
|
|
|
- la_GetSelectionIslands(mo,&md,ex->SelectMode);
|
|
|
- int success=la_MakeFacesFromIslands(mo,&md); if(success){ tnsMMeshCalculateNormal(mo); }
|
|
|
- la_ClearIslands(&md);
|
|
|
+ if(mo->Base.Type==TNS_OBJECT_MESH && mo->Mode==TNS_MESH_EDIT_MODE){
|
|
|
+ MMakeData md={0};
|
|
|
+ la_GetSelectionIslands(mo,&md,ex->SelectMode);
|
|
|
+ int success=la_MakeFacesFromIslands(mo,&md); if(success){ tnsMMeshCalculateNormal(mo); }
|
|
|
+ la_ClearIslands(&md);
|
|
|
|
|
|
- tnsMMeshRefreshIndex(mo);
|
|
|
- tnsMMeshEnsureSelection(mo,ex->SelectMode);
|
|
|
- tnsInvalidateMeshBatch(mo);
|
|
|
- if(laRecordInstanceDifferences(mo, "tns_mesh_object")) laPushDifferences("Make primitives", TNS_HINT_GEOMETRY);
|
|
|
- laNotifyUsers("tns.world");
|
|
|
+ tnsMMeshRefreshIndex(mo);
|
|
|
+ tnsMMeshEnsureSelection(mo,ex->SelectMode);
|
|
|
+ tnsInvalidateMeshBatch(mo);
|
|
|
+ if(laRecordInstanceDifferences(mo, "tns_mesh_object")) laPushDifferences("Make primitives", TNS_HINT_GEOMETRY);
|
|
|
+ laNotifyUsers("tns.world");
|
|
|
+ }elif(so->Base.Type==TNS_OBJECT_SHAPE && so->Mode==TNS_MESH_EDIT_MODE){
|
|
|
+ if(tnsShapeConnectSelected(so)){
|
|
|
+ laRecordInstanceDifferences(so, "tns_shape_object"); laPushDifferences("Connect shapes", TNS_HINT_GEOMETRY);
|
|
|
+ laNotifyUsers("tns.world");
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
return LA_FINISHED;
|
|
|
}
|
|
@@ -1566,9 +1604,10 @@ int OPINV_Duplicate(laOperator *a, laEvent *e){
|
|
|
if(!a->This || !a->This->EndInstance){ return 0; }
|
|
|
laCanvasExtra* ex=a->This->EndInstance; tnsCamera*c=ex->ViewingCamera; laUiItem* ui=ex->ParentUi;
|
|
|
tnsObject*root=ui?ui->PP.EndInstance:0; if(!root) return LA_CANCELED;
|
|
|
- tnsMeshObject* mo=root->Active; int ran=0;
|
|
|
+ tnsMeshObject* mo=root->Active; tnsShapeObject* so=mo; int ran=0;
|
|
|
|
|
|
- if(!mo || mo->Mode==TNS_MESH_EDIT_MODE){ return LA_CANCELED; }
|
|
|
+ if(!mo || (mo->Base.Type==TNS_OBJECT_MESH&&mo->Mode==TNS_MESH_EDIT_MODE)||
|
|
|
+ (so->Base.Type==TNS_OBJECT_SHAPE&&so->Mode==TNS_MESH_EDIT_MODE)){ return LA_CANCELED; }
|
|
|
|
|
|
laListHandle pending={0}; la_PopulateSelectedObjects(root,&pending,0);
|
|
|
tnsMeshObject* o; tnsMeshObject* no; laListItemPointer* lip;
|
|
@@ -1971,12 +2010,14 @@ void la_RegisterModellingOperators(){
|
|
|
at=laCreateOperatorType("M_unparent", "Unparent", "Unparent selected objects", 0, 0, 0, OPINV_MakeParent, OPMOD_FinishOnData, 0, 0);
|
|
|
at->UiDefine = laui_Unparent;
|
|
|
laCreateOperatorType("M_extrude", "Extrude", "Extrude parts of the mesh", 0, 0, 0, OPINV_Extrude, OPMOD_Transformation, 0, 0);
|
|
|
- at=laCreateOperatorType("M_delete", "Delete", "Delete parts of the mesh", 0, 0, 0, OPINV_Delete, OPMOD_FinishOnData, 0, 0);
|
|
|
+ at=laCreateOperatorType("M_delete", "Delete", "Delete parts of the mesh", 0, 0, OPEXT_FreeUserData, OPINV_Delete, OPMOD_FinishOnData, 0, 0);
|
|
|
+ pc = laDefineOperatorProps(at, 1);
|
|
|
+ laAddIntProperty(pc,"context","Context","Delete menu context",0,0,0,0,0,0,0,0,offsetof(MDeleteData,Context),0,0,0,0,0,0,0,0,0,0,0);
|
|
|
at->UiDefine=laui_Delete;
|
|
|
laCreateOperatorType("M_make", "Make", "Make mesh primitive from selected ones", 0, 0, 0, OPINV_Make, 0, 0, 0);
|
|
|
laCreateOperatorType("M_subdiv", "Subdiv", "Subdivide edges", 0, 0, 0, OPINV_Subdiv, 0, 0, 0);
|
|
|
- at=laCreateOperatorType("M_add", "Add", "Add mesh or primitives", 0, 0, 0, OPINV_Add, OPMOD_FinishOnData, 0, 0);
|
|
|
- at->UiDefine=laui_Add; pc = laDefineOperatorProps(at, 2);
|
|
|
+ at=laCreateOperatorType("M_add", "Add", "Add mesh or primitives", 0, 0, OPEXT_FreeUserData, OPINV_Add, OPMOD_FinishOnData, 0, 0);
|
|
|
+ at->UiDefine=laui_Add; pc = laDefineOperatorProps(at, 1);
|
|
|
p=laAddEnumProperty(pc,"context","Context","Context of adding",0,0,0,0,0,offsetof(laObjectAddData,Context),0,0,0,0,0,0,0,0,0,0);
|
|
|
laAddEnumItemAs(p,"OBJECT","Object","Object context",LA_ADD_CTX_OBJECT,0);
|
|
|
laAddEnumItemAs(p,"MESH","Mesh","Mesh context",LA_ADD_CTX_MESH,0);
|