|  | @@ -37,6 +37,10 @@ tnsSPoint* tnsShapeInsertSPointAt(tnsShape* s, tnsSPoint* pivot, int before){
 | 
	
		
			
				|  |  |      if(before){ lstInsertItemBefore(&s->Points,sp,pivot); }
 | 
	
		
			
				|  |  |      else{ lstInsertItemAfter(&s->Points,sp,pivot); }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +void tnsShapeSetHole(tnsShape* s, int closed, int toggle){
 | 
	
		
			
				|  |  | +    if(toggle) tnsShapeSetHole(s,!(s->flags&TNS_SHAPE_HOLE),0);
 | 
	
		
			
				|  |  | +    else{ if(closed) s->flags|=TNS_SHAPE_HOLE; else s->flags&=(~TNS_SHAPE_HOLE); }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  void tnsShapeSetClosed(tnsShape* s, int closed, int toggle){
 | 
	
		
			
				|  |  |      if(toggle) tnsShapeSetClosed(s,!(s->flags&TNS_SHAPE_CLOSED),0);
 | 
	
		
			
				|  |  |      else{ if(closed) s->flags|=TNS_SHAPE_CLOSED; else s->flags&=(~TNS_SHAPE_CLOSED); }
 | 
	
	
		
			
				|  | @@ -245,7 +249,7 @@ void tns_DrawShape(tnsShape* s, real* override_color, int DrawEdit, real PointSc
 | 
	
		
			
				|  |  |          nvgShapeAntiAlias(vg,1);
 | 
	
		
			
				|  |  |          return;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    nvgBeginPath(vg);
 | 
	
		
			
				|  |  | +    if(DrawEdit){ nvgBeginPath(vg); }
 | 
	
		
			
				|  |  |      tnsSPoint* sp1=s->Points.pFirst; nvgMoveTo(vg,sp1->p[0],sp1->p[1]); if(sp1->flags&TNS_SPOINT_SELECTED){HasSelection=1;}
 | 
	
		
			
				|  |  |      for(tnsSPoint* sp=sp1->Item.pNext;sp;sp=sp->Item.pNext){
 | 
	
		
			
				|  |  |          if(sp->flags&TNS_SPOINT_SELECTED){HasSelection=1;}
 | 
	
	
		
			
				|  | @@ -265,8 +269,10 @@ void tns_DrawShape(tnsShape* s, real* override_color, int DrawEdit, real PointSc
 | 
	
		
			
				|  |  |          if(sp->flags&TNS_SPOINT_BEZIER){ tnsVectorAccum2d(c2,sp->dl); }
 | 
	
		
			
				|  |  |          nvgBezierTo(vg,c1[0],c1[1],c2[0],c2[1],sp->p[0],sp->p[1]);
 | 
	
		
			
				|  |  |          nvgClosePath(vg);
 | 
	
		
			
				|  |  | -        nvgFillColor(vg, override_color?nvgRGBAf(LA_COLOR4(override_color)):nvgRGBAf(0.8,0.8,0.8,1));
 | 
	
		
			
				|  |  | -        nvgFill(vg);
 | 
	
		
			
				|  |  | +        nvgPathWinding(vg,(s->flags&TNS_SHAPE_HOLE)?NVG_HOLE:NVG_SOLID);
 | 
	
		
			
				|  |  | +        if(!(s->flags&TNS_SHAPE_HOLE)){
 | 
	
		
			
				|  |  | +            nvgFillColor(vg, override_color?nvgRGBAf(LA_COLOR4(override_color)):nvgRGBAf(0.8,0.8,0.8,1));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      if(DrawEdit || (!closed)){
 | 
	
		
			
				|  |  |          tnsVector4d color; tnsVectorCopy4d(laAccentColor(LA_BT_VERTEX),color);
 | 
	
	
		
			
				|  | @@ -310,8 +316,18 @@ void tnsDrawShapeObjectShapes(tnsEvaluatedInstance* ei, la3DObjectDrawExtra* de,
 | 
	
		
			
				|  |  |          nvgTranslate(vg,ei->Mat[12],-ei->Mat[13]);
 | 
	
		
			
				|  |  |          nvgScale(vg,sca[0],-sca[1]); nvgRotate(vg,rot[2]);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    for(tnsShape*s=so->Shapes.pFirst;s;s=s->Item.pNext){
 | 
	
		
			
				|  |  | -        tns_DrawShape(s,override_color,DrawEdit?DrawEdit:(so->Mode==TNS_MESH_EDIT_MODE),de->PointScale/sca[0]);
 | 
	
		
			
				|  |  | +    if(DrawEdit!=2){ int begun=0; int ishole=0,nexthole=0;
 | 
	
		
			
				|  |  | +        for(tnsShape*s=so->Shapes.pFirst;s;s=s->Item.pNext){
 | 
	
		
			
				|  |  | +            if(!begun){ begun=1; nvgBeginPath(vg); }
 | 
	
		
			
				|  |  | +            ishole=s->flags&TNS_SHAPE_HOLE; tnsShape* ns=s->Item.pNext; nexthole=ns?(ns->flags&TNS_SHAPE_HOLE):0;
 | 
	
		
			
				|  |  | +            tns_DrawShape(s,override_color,0,de->PointScale/sca[0]);
 | 
	
		
			
				|  |  | +            if((!ns) || (ishole&&(!nexthole))){ nvgFill(vg); begun=0; }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if(DrawEdit||so->Mode==TNS_MESH_EDIT_MODE){
 | 
	
		
			
				|  |  | +        for(tnsShape*s=so->Shapes.pFirst;s;s=s->Item.pNext){
 | 
	
		
			
				|  |  | +            tns_DrawShape(s,override_color,DrawEdit?DrawEdit:so->Mode==TNS_MESH_EDIT_MODE,de->PointScale/sca[0]);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      nvgRestore(vg);
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -435,6 +451,26 @@ int OPINV_SetShapeClosed(laOperator *a, laEvent *e){
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      return LA_FINISHED;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +int OPINV_SetShapeHole(laOperator *a, laEvent *e){
 | 
	
		
			
				|  |  | +    laCanvasExtra* ex=a->This->EndInstance; laUiItem* ui=ex->ParentUi;
 | 
	
		
			
				|  |  | +    tnsObject*root=ui?ui->PP.EndInstance:0;
 | 
	
		
			
				|  |  | +    if(!root || !root->Active || root->Active->Type!=TNS_OBJECT_SHAPE) return LA_FINISHED;
 | 
	
		
			
				|  |  | +    tnsShapeObject* so=root->Active; int ran=0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    char* mode=strGetArgumentString(a->ExtraInstructionsP,"mode");
 | 
	
		
			
				|  |  | +    int set=2; if(strSame(mode,"HOLE")){ set=1; }elif(strSame(mode,"FILL")){ set=0; }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    for(tnsShape*s=so->Shapes.pFirst;s;s=s->Item.pNext){
 | 
	
		
			
				|  |  | +        for(tnsSPoint*sp=s->Points.pFirst;sp;sp=sp->Item.pNext){ if(!(sp->flags&TNS_SPOINT_SELECTED)) continue;
 | 
	
		
			
				|  |  | +            tnsShapeSetHole(s,set,set==2); ran=1; break;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if(ran){
 | 
	
		
			
				|  |  | +        laRecordInstanceDifferences(so,"tns_shape_object"); laPushDifferences("Open/Close shape",TNS_HINT_GEOMETRY);
 | 
	
		
			
				|  |  | +        laNotifyUsers("tns.world");
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return LA_FINISHED;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  void la_RegisterShapeOperators(){
 | 
	
		
			
				|  |  |      laPropContainer *pc; laProp *p;
 | 
	
		
			
				|  |  |      laOperatorType *at; laEnumProp *ep;
 | 
	
	
		
			
				|  | @@ -442,4 +478,5 @@ void la_RegisterShapeOperators(){
 | 
	
		
			
				|  |  |      at=laCreateOperatorType("M_set_point_handle", "Set Point Handle", "Set handle type of selected points",OPCHK_IsAnyPointSelected,0,0,OPINV_SetPointHandle,OPMOD_FinishOnData,0,0);
 | 
	
		
			
				|  |  |      at->UiDefine=laui_SetPointHandle;
 | 
	
		
			
				|  |  |      at=laCreateOperatorType("M_set_shape_closed", "Set Shape Closed", "Set shape closed or open",OPCHK_IsAnyPointSelected,0,0,OPINV_SetShapeClosed,0,0,0);
 | 
	
		
			
				|  |  | +    at=laCreateOperatorType("M_set_shape_hole", "Set Shape Hole", "Set shape as hole or fill",OPCHK_IsAnyPointSelected,0,0,OPINV_SetShapeHole,0,0,0);
 | 
	
		
			
				|  |  |  }
 |