diff --git a/Designing/Main.lua b/Designing/Main.lua index 7670f00..d40624c 100644 --- a/Designing/Main.lua +++ b/Designing/Main.lua @@ -74,7 +74,7 @@ WinCreate.ImportProfile( sProfilePath) -- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPES.ROUND_ARC, { WindowWidth, WindowHeight}, vFrameJoints, vFrameDims) -- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPES.SEGMENTAL_ARC, { 1500, 1800, 2200}, vFrameJoints, vFrameDims) -- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPES.CHAMFER, { WindowWidth, WindowHeight, WindowHeight + 500}, vFrameJoints, { dFrameDim, dFrameDim, dFrameDim, dFrameDim, dFrameDim}) --- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPES.POINTED_ARC, { 1500, 1500, 2400}, vFrameJoints, { dFrameDim, dFrameDim, dFrameDim, dFrameDim, dFrameDim}) +-- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPES.POINTED_ARC, { 1200, 1500, 2400}, vFrameJoints, { dFrameDim, dFrameDim, dFrameDim, dFrameDim, dFrameDim}) -- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPES.TRG, { 1500, 1500, 500}, { FrameJointType, FrameJointType, FrameJointType}, { dFrameDim, dFrameDim, dFrameDim}) -- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPES.THREE_CENTER_ARC, { 1500, 1500, 1800, 200}, vFrameJoints, { dFrameDim, dFrameDim, dFrameDim, dFrameDim, dFrameDim, dFrameDim}) @@ -91,6 +91,7 @@ WinCreate.ImportProfile( sProfilePath) -- { WIN_MEASURE.PROPORTIONAL, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PROPORTIONAL}, { 1, 50, 1}, false) + ------------------------ Cambi profilo ------------------------ -- vetro / anta @@ -193,6 +194,79 @@ WinCreate.ImportProfile( sProfilePath) +------------------------ Cambi profilo su split ------------------------ + +-- sotto: vetro / anta | sopra: vetro +-- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.HORIZONTAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, {}) +-- local nFill1 = WinCreate.AddFill( vAreas[2], WIN_FILLTYPES.GLASS) +-- local vAreas2 = WinCreate.AddSplits( vAreas[1], WIN_SPLITORIENTATION.VERTICAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, {}) +-- local nFill3 = WinCreate.AddFill( vAreas2[1], WIN_FILLTYPES.GLASS) +-- local nSash = WinCreate.AddSash( vAreas2[2], vSashJoints) +-- local nFill2 = WinCreate.AddFill( nSash, WIN_FILLTYPES.GLASS) + +-- sotto: vetro / anta / vetro | sopra: anta / vetro +-- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.HORIZONTAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}) +-- local vAreas1 = WinCreate.AddSplits( vAreas[1], WIN_SPLITORIENTATION.VERTICAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 100/3, 100/3, 100/3}) +-- local nFill1 = WinCreate.AddFill( vAreas1[1], WIN_FILLTYPES.GLASS) +-- local nSash1 = WinCreate.AddSash( vAreas1[2], vSashJoints) +-- local nFill2 = WinCreate.AddFill( nSash1, WIN_FILLTYPES.GLASS) +-- local nFill3 = WinCreate.AddFill( vAreas1[3], WIN_FILLTYPES.GLASS) +-- local vAreas2 = WinCreate.AddSplits( vAreas[2], WIN_SPLITORIENTATION.VERTICAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}) +-- local nSash2 = WinCreate.AddSash( vAreas2[1], vSashJoints) +-- local nFill4 = WinCreate.AddFill( nSash2, WIN_FILLTYPES.GLASS) +-- local nFill5 = WinCreate.AddFill( vAreas2[2], WIN_FILLTYPES.GLASS) +-- -- WinCreate.AddSplits( nFill1, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 100/3, 100/3, 100/3}, nil, false, false, WIN_MUNTINFILL_SIDES.BOTH) +-- -- WinCreate.AddSplits( nFill2, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 100/3, 100/3, 100/3}, nil, false, false, WIN_MUNTINFILL_SIDES.BOTH) +-- -- WinCreate.AddSplits( nFill3, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 100/3, 100/3, 100/3}, nil, false, false, WIN_MUNTINFILL_SIDES.BOTH) +-- -- WinCreate.AddSplits( nFill4, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 100/3, 100/3, 100/3}, nil, false, false, WIN_MUNTINFILL_SIDES.BOTH) +-- -- WinCreate.AddSplits( nFill5, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 100/3, 100/3, 100/3}, nil, false, false, WIN_MUNTINFILL_SIDES.BOTH) + +-- sotto: vetro / anta / vetro | sopra: vetro / vetro +-- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.HORIZONTAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 70, 30}, {80}) +-- local vAreas1 = WinCreate.AddSplits( vAreas[1], WIN_SPLITORIENTATION.VERTICAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.3333, 33.33333, 33.33333}, {80,80}) +-- local nFill1 = WinCreate.AddFill( vAreas1[1], WIN_FILLTYPES.GLASS) +-- local nSash = WinCreate.AddSash( vAreas1[2], vSashJoints) +-- local nFill2 = WinCreate.AddFill( nSash, WIN_FILLTYPES.GLASS) +-- local nFill3 = WinCreate.AddFill( vAreas1[3], WIN_FILLTYPES.GLASS) +-- local vAreas2 = WinCreate.AddSplits( vAreas[2], WIN_SPLITORIENTATION.VERTICAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, {80,80}) +-- local nFill4 = WinCreate.AddFill( vAreas2[1], WIN_FILLTYPES.GLASS) +-- local nFill5 = WinCreate.AddFill( vAreas2[2], WIN_FILLTYPES.GLASS) + +-- sotto: anta-vetro / anta / vetro | sopra: vetro +-- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.HORIZONTAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 70, 30}) +-- local vAreas1 = WinCreate.AddSplits( vAreas[1], WIN_SPLITORIENTATION.VERTICAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.3333, 33.33333, 33.33333}) +-- local vAreas2 = WinCreate.AddSplits( vAreas1[1], WIN_SPLITORIENTATION.HORIZONTAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}) +-- local nFill1 = WinCreate.AddFill( vAreas2[1], WIN_FILLTYPES.GLASS) +-- local nSash1 = WinCreate.AddSash( vAreas2[2], vSashJoints) +-- local nFill2 = WinCreate.AddFill( nSash1, WIN_FILLTYPES.GLASS) +-- local nSash = WinCreate.AddSash( vAreas1[2], vSashJoints) +-- local nFill3 = WinCreate.AddFill( nSash, WIN_FILLTYPES.GLASS) +-- local nFill4 = WinCreate.AddFill( vAreas1[3], WIN_FILLTYPES.GLASS) +-- local nFill5 = WinCreate.AddFill( vAreas[2], WIN_FILLTYPES.GLASS) + +-- sotto: vetro | sopra: anta / vetro - vetro / anta +-- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.HORIZONTAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 70, 30}) +-- WinCreate.AddFill( vAreas[1], WIN_FILLTYPES.GLASS) +-- local vAreas1 = WinCreate.AddSplits( vAreas[2], WIN_SPLITORIENTATION.VERTICAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.3333, 33.33333, 33.33333}, {80,80}) +-- local nSash1 = WinCreate.AddSash( vAreas1[1], vSashJoints) +-- WinCreate.AddFill( nSash1, WIN_FILLTYPES.GLASS) +-- local nSash2 = WinCreate.AddSash( vAreas1[3], vSashJoints) +-- WinCreate.AddFill( nSash2, WIN_FILLTYPES.GLASS) +-- local vAreas2 = WinCreate.AddSplits( vAreas1[2], WIN_SPLITORIENTATION.HORIZONTAL, {WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}) +-- WinCreate.AddFill( vAreas2[2], WIN_FILLTYPES.GLASS) +-- WinCreate.AddFill( vAreas2[1], WIN_FILLTYPES.GLASS) + +-- sotto: vetro / anta | sopra: anta / vetro +-- local vAreas = WinCreate.AddGridSplits( nFrameId, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, true) +-- WinCreate.AddFill( vAreas[1], WIN_FILLTYPES.GLASS) +-- local nSash1 = WinCreate.AddSash( vAreas[2], vSashJoints) +-- WinCreate.AddFill( nSash1, WIN_FILLTYPES.GLASS) +-- local nSash2 = WinCreate.AddSash( vAreas[3], vSashJoints) +-- WinCreate.AddFill( nSash2, WIN_FILLTYPES.GLASS) +-- WinCreate.AddFill( vAreas[4], WIN_FILLTYPES.GLASS) + + + ------------------------ Alzante Scorrevole ------------------------ -- vFrameDims = { 55, 55, 55, 55} @@ -207,24 +281,24 @@ WinCreate.ImportProfile( sProfilePath) -- local nFill2 = WinCreate.AddFill( vSash[2], WIN_FILLTYPES.GLASS) -- -- WinCreate.AddSplits( nFill1, WIN_SPLITORIENTATION.HORIZONTAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, nil, false, false, WIN_MUNTINFILL_SIDES.BOTH) -- -- WinCreate.AddSplits( nFill2, WIN_SPLITORIENTATION.HORIZONTAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, nil, false, false, WIN_MUNTINFILL_SIDES.BOTH) --- local nSashGrpId = EgtGetParent( vSash[1]) --- WinCreate.AddHardware( nSashGrpId, '000592', 'Sx') +-- -- local nSashGrpId = EgtGetParent( vSash[1]) +-- -- WinCreate.AddHardware( nSashGrpId, '000592', 'Sx') -- anta mobile a dx -- local vSash = WinCreate.AddSashGroup( nFrameId, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, bDaylight, { vSashJoints, vSashJoints}, { vSashDims, vSashDims}, -- { WIN_SASHTYPES.SLIDE_FIXED, WIN_SASHTYPES.SLIDE_MOVABLE}, { WIN_OPENING_TYPES.FIXED, WIN_OPENING_TYPES.COPLANARSLIDE_LEFT}) -- WinCreate.AddFill( vSash[1], WIN_FILLTYPES.GLASS) -- WinCreate.AddFill( vSash[2], WIN_FILLTYPES.GLASS) --- local nSashGrpId = EgtGetParent( vSash[1]) --- WinCreate.AddHardware( nSashGrpId, '000592', 'Dx') +-- -- local nSashGrpId = EgtGetParent( vSash[1]) +-- -- WinCreate.AddHardware( nSashGrpId, '000592', 'Dx') -- 2 ante mobili, sx davanti -- local vSash = WinCreate.AddSashGroup( nFrameId, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, bDaylight, { vSashJoints, vSashJoints}, { vSashDims, vSashDims}, -- { WIN_SASHTYPES.SLIDE_MOVABLE, WIN_SASHTYPES.SLIDE_MOVABLE_BACK}, { WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT, WIN_OPENING_TYPES.COPLANARSLIDE_LEFT}) -- WinCreate.AddFill( vSash[1], WIN_FILLTYPES.GLASS) -- WinCreate.AddFill( vSash[2], WIN_FILLTYPES.GLASS) --- local nSashGrpId = EgtGetParent( vSash[1]) --- WinCreate.AddHardware( nSashGrpId, '000593', 'Sx') +-- -- local nSashGrpId = EgtGetParent( vSash[1]) +-- -- WinCreate.AddHardware( nSashGrpId, '000593', 'Sx') -- 2 ante mobili, dx davanti -- local vSash = WinCreate.AddSashGroup( nFrameId, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, bDaylight, { vSashJoints, vSashJoints}, { vSashDims, vSashDims}, @@ -236,7 +310,7 @@ WinCreate.ImportProfile( sProfilePath) -- 4 ante, le centrali sono mobili -- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPES.RECT, { 4500, 2100}, vFrameJoints, vFrameDims) --- -- WinCreate.AddThreshold( nFrameId, 'Threshold') +-- WinCreate.AddThreshold( nFrameId, 'Threshold') -- local vSash = WinCreate.AddSashGroup( nFrameId, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 25, 25, 25, 25}, bDaylight, -- { vSashJoints, vSashJoints, vSashJoints, vSashJoints}, { vSashDims, vSashDims, vSashDims, vSashDims}, -- { WIN_SASHTYPES.SLIDE_FIXED, WIN_SASHTYPES.SLIDE_MOVABLE, WIN_SASHTYPES.SLIDE_MOVABLE, WIN_SASHTYPES.SLIDE_FIXED}, @@ -245,8 +319,8 @@ WinCreate.ImportProfile( sProfilePath) -- WinCreate.AddFill( vSash[2], WIN_FILLTYPES.GLASS) -- WinCreate.AddFill( vSash[3], WIN_FILLTYPES.GLASS) -- WinCreate.AddFill( vSash[4], WIN_FILLTYPES.GLASS) --- local nSashGrpId = EgtGetParent( vSash[1]) --- WinCreate.AddHardware( nSashGrpId, '000594', 'Dx') +-- -- local nSashGrpId = EgtGetParent( vSash[1]) +-- -- WinCreate.AddHardware( nSashGrpId, '000594', 'Dx') -- 4 ante mobili -- local nFrameId = WinCreate.CreateFrame( WIN_FRAME_TYPES.RECT, { 4500, 2100}, vFrameJoints, vFrameDims) @@ -259,16 +333,16 @@ WinCreate.ImportProfile( sProfilePath) -- local nFill2 = WinCreate.AddFill( vSash[2], WIN_FILLTYPES.GLASS) -- local nFill3 = WinCreate.AddFill( vSash[3], WIN_FILLTYPES.GLASS) -- local nFill4 = WinCreate.AddFill( vSash[4], WIN_FILLTYPES.GLASS) --- -- WinCreate.AddGridSplits( nFill1, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, --- -- { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.333, 33.333, 33.333}, true, nil, nil, WIN_MUNTINFILL_SIDES.BOTH) --- -- WinCreate.AddGridSplits( nFill2, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, --- -- { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.333, 33.333, 33.333}, true, nil, nil, WIN_MUNTINFILL_SIDES.BOTH) --- -- WinCreate.AddGridSplits( nFill3, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, --- -- { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.333, 33.333, 33.333}, true, nil, nil, WIN_MUNTINFILL_SIDES.BOTH) --- -- WinCreate.AddGridSplits( nFill4, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, --- -- { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.333, 33.333, 33.333}, true, nil, nil, WIN_MUNTINFILL_SIDES.BOTH) --- local nSashGrpId = EgtGetParent( vSash[1]) --- WinCreate.AddHardware( nSashGrpId, '000595', 'Dx') +-- WinCreate.AddGridSplits( nFill1, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, +-- { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.333, 33.333, 33.333}, true, nil, nil, WIN_MUNTINFILL_SIDES.BOTH) +-- WinCreate.AddGridSplits( nFill2, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, +-- { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.333, 33.333, 33.333}, true, nil, nil, WIN_MUNTINFILL_SIDES.BOTH) +-- WinCreate.AddGridSplits( nFill3, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, +-- { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.333, 33.333, 33.333}, true, nil, nil, WIN_MUNTINFILL_SIDES.BOTH) +-- WinCreate.AddGridSplits( nFill4, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, +-- { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.333, 33.333, 33.333}, true, nil, nil, WIN_MUNTINFILL_SIDES.BOTH) +-- -- local nSashGrpId = EgtGetParent( vSash[1]) +-- -- WinCreate.AddHardware( nSashGrpId, '000595', 'Dx') @@ -279,9 +353,9 @@ WinCreate.ImportProfile( sProfilePath) -- WinCreate.AddFill( nFrameId, WIN_FILLTYPES.GLASS) -- divisione orizzontale / verticale --- WinCreate.AddBottomRail( nFrameId, 2) --- -- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.HORIZONTAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 70, 30}, { 60}) --- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 70, 30}, { 60}) +-- WinCreate.AddBottomRail( nFrameId, 3, {}) +-- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.HORIZONTAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 70, 30}, { 70}) +-- -- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 70, 30}, { 60}) -- WinCreate.AddFill( vAreas[1], WIN_FILLTYPES.GLASS) -- WinCreate.AddFill( vAreas[2], WIN_FILLTYPES.GLASS) @@ -296,8 +370,8 @@ WinCreate.ImportProfile( sProfilePath) -- WinCreate.AddFill( vAreas3[2], WIN_FILLTYPES.GLASS) -- divisione verticale ed orizzontale (2) --- WinCreate.AddBottomRail( nFrameId, 1) --- local vAreas = WinCreate.AddGridSplits( nFrameId, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, +-- WinCreate.AddBottomRail( nFrameId, 2) +-- local vAreas = WinCreate.AddGridSplits( nFrameId, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 70, 30}, -- true, { 100}, { 60}) -- WinCreate.AddFill( vAreas[1], WIN_FILLTYPES.GLASS) -- WinCreate.AddFill( vAreas[2], WIN_FILLTYPES.GLASS) @@ -309,6 +383,7 @@ WinCreate.ImportProfile( sProfilePath) ------------------------ Finestre con anta singola ------------------------ -- standard +-- WinCreate.AddThreshold( nFrameId, 'Threshold') -- local nSashId = WinCreate.AddSash( nFrameId, vSashJoints, vSashDims, WIN_OPENING_TYPES.TILTTURN_LEFT) -- WinCreate.AddBottomRail( nSashId, 2, { 90, 60}) -- WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) @@ -316,7 +391,7 @@ WinCreate.ImportProfile( sProfilePath) -- divisione orizzontale / verticale -- local nSashId = WinCreate.AddSash( nFrameId, vSashJoints, vSashDims, WIN_OPENING_TYPES.TILTTURN_LEFT) -- WinCreate.AddBottomRail( nSashId, 1, { 100}) --- -- local vAreas = WinCreate.AddSplits( nSashId, WIN_SPLITORIENTATION.HORIZONTAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}) +-- -- local vAreas = WinCreate.AddSplits( nSashId, WIN_SPLITORIENTATION.HORIZONTAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 70, 30}) -- local vAreas = WinCreate.AddSplits( nSashId, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 50, 50}) -- WinCreate.AddFill( vAreas[1], WIN_FILLTYPES.GLASS) -- WinCreate.AddFill( vAreas[2], WIN_FILLTYPES.GLASS) @@ -350,7 +425,7 @@ WinCreate.ImportProfile( sProfilePath) -- WinCreate.AddFill( nSash2Id, WIN_FILLTYPES.GLASS) -- tre ante --- -- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.ABSOLUTE, WIN_MEASURE.ABSOLUTE, WIN_MEASURE.ABSOLUTE}, { 500, 200, 800}, { 95, 95}) +-- -- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.ABSOLUTE, WIN_MEASURE.ABSOLUTE, WIN_MEASURE.PROPORTIONAL}, { 500, 200, 1}, { 95, 95}) -- -- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.PROPORTIONAL, WIN_MEASURE.PROPORTIONAL, WIN_MEASURE.PROPORTIONAL}, { 1, 1, 1}, { 95, 95}) -- local vAreas = WinCreate.AddSplits( nFrameId, WIN_SPLITORIENTATION.VERTICAL, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.333, 33.333, 33.333}, { 95, 95}) -- local nSash1Id = WinCreate.AddSash( vAreas[1], vSashJoints, vSashDims) @@ -415,8 +490,8 @@ WinCreate.ImportProfile( sProfilePath) -- WinCreate.AddFill( vSashes[2], WIN_FILLTYPES.GLASS) -- battente / ricevente / ricevente --- local vSashes = WinCreate.AddSashGroup( nFrameId, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 33.333, 33.333, 33.333}, bDaylight, --- { vSashJoints, vSashJoints, vSashJoints}, { vSashDims, vSashDims, vSashDims}, +-- local vSashes = WinCreate.AddSashGroup( nFrameId, { WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE, WIN_MEASURE.PERCENTAGE}, { 100/3, 100/3, !00/3}, bDaylight, +-- { vSashJoints, vSashJoints, vSashJoints}, { vSashDims, vSashDims, vSashDims}, -- { WIN_SASHTYPES.ACTIVE, WIN_SASHTYPES.INACTIVE_IN, WIN_SASHTYPES.INACTIVE_OUT}, -- { WIN_OPENING_TYPES.TURNONLY_LEFT, WIN_OPENING_TYPES.TURNONLY_RIGHT, WIN_OPENING_TYPES.TURNONLY_RIGHT}) -- WinCreate.AddFill( vSashes[1], WIN_FILLTYPES.GLASS) @@ -576,7 +651,7 @@ WinCreate.ImportProfile( sProfilePath) -- local nSashId = WinCreate.AddSash( nFrameId, vSashJoints, vSashDims, WIN_OPENING_TYPES.TILTTURN_LEFT) -- WinCreate.AddFill( nSashId, WIN_FILLTYPES.GLASS) -- WinCreate.AddHardware( nSashId, '000558', 'Sx') --- -- WinCreate.AddHardware( nSashId, '000545', 'Sx') -- aria 4, errato ma crea alcune lavorazioni in più +-- WinCreate.AddHardware( nSashId, '000545', 'Sx') -- aria 4, errato ma crea alcune lavorazioni in più -- -- WinCreate.AddHardware( nSashId, '000596', 'Sx') -- arco a tutto sesto -- -- WinCreate.AddHardware( nSashId, '000597', 'Sx') -- arco ribassato -- -- WinCreate.AddHardware( nSashId, '000604', 'Sx') -- trapezio diff --git a/Designing/WinConst.lua b/Designing/WinConst.lua index 06a8f37..0ec5c30 100644 --- a/Designing/WinConst.lua +++ b/Designing/WinConst.lua @@ -314,6 +314,8 @@ WIN_SASH_REF = 'SashRef' WIN_SASH_DEPTH = 'SashDepth' WIN_RAD_REF = 'RefRad' WIN_EXTRA_DIST = 'ExtraDist' +WIN_SASH_DIAM = 'SashDiam' +WIN_FILL_DIAM = 'FillDiam' -- per lavorazioni WIN_PRC_OVERMAT_IN = 'OVERMAT_IN' WIN_PRC_OVERMAT_OUT = 'OVERMAT_OUT' @@ -405,10 +407,13 @@ WIN_PRF_CHANGE_TYPES = { -- binario WIN_MIXED_CURVES = 'ProfileChangeCurves' WIN_MIXED_MILLING = 'ProfileChangeMilling' WIN_MIXED_SPLIT_REF = 'MixedSplitRef' -WIN_FILL_ON_SPLIT_RIGHT = 'FillOnSplitRight' +WIN_MIXED_BISECTOR_REF = 'MixedBisectorRef' +WIN_MIXED_SASHFILL = 'SashFill' +WIN_MIXED_ONSTART = 'MixedOnStart' WIN_MIXED_START_CHILDREN = 'StartChildrenType' WIN_MIXED_END_CHILDREN = 'EndChildrenType' - +WIN_MIXED_PREV = 'MixedPrev' +WIN_MIXED_NEXT = 'MixedNext' -- SOLIDI WIN_SOLID = 'Solid' diff --git a/Designing/WinLib/WinCalculate.lua b/Designing/WinLib/WinCalculate.lua index d215001..a409507 100644 --- a/Designing/WinLib/WinCalculate.lua +++ b/Designing/WinLib/WinCalculate.lua @@ -247,6 +247,38 @@ local function CreateCurveExtension( nCrvId, nGrpId) return nExtId end +--------------------------------------------------------------------- +local function CreateCurveOpenExtension( nOutlineId, nGrp, bTangS, bTangE) + + local nExtCrv + local dExtraLinearLen = 400 + if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE then + -- se tratto lineare non ci sono problemi per l'estensione + nExtCrv = EgtCopyGlob( nOutlineId, nGrp) + EgtExtendCurveStartByLen( nExtCrv, dExtraLinearLen) + EgtExtendCurveEndByLen( nExtCrv, dExtraLinearLen) + + else + nExtCrv = EgtCurveCompo( nGrp, nOutlineId, false) + -- calcolo la lunghezza di estensione per l'arco in modo che non si chiuda in una circonferenza + local dRad = EgtArcRadius( nOutlineId) + local dExtraLen = 0.5 * ( 2 * pi * dRad - EgtCurveLength( nOutlineId)) - 2 + + if bTangS then + EgtAddCurveCompoLineTg( nExtCrv, dExtraLinearLen, false) + else + EgtExtendCurveStartByLen( nExtCrv, dExtraLen) + end + + if bTangE then + EgtAddCurveCompoLineTg( nExtCrv, dExtraLinearLen, true) + else + EgtExtendCurveEndByLen( nExtCrv, dExtraLen) + end + end + return nExtCrv +end + --------------------------------------------------------------------- -- funzione che data una lista di curve ordinate e orientate che creano una curva chiusa, ne individua la regione definita local function CalcIntersectionRegion( vCrvs, nGrp) @@ -276,7 +308,7 @@ local function CalcIntersectionRegion( vCrvs, nGrp) table.insert( tArcs, { nCrvId = nCrvId, nOrigId = vCrvs[i], dRad = EgtArcRadius( vCrvs[i])}) else - -- se composita deve contenere un arco, recupero il suo raggio + -- se composita potrebbe contenere un arco, recupero il suo raggio local _, dEnd = EgtCurveDomain( vCrvs[i]) local dRad = 0 for j = 0, dEnd - 1 do @@ -361,7 +393,7 @@ local function CalcIntersectionRegion( vCrvs, nGrp) -- ricostruisco la superficie nSurfId = EgtSurfFlatRegion( nGrpTmp, nCrvBorder) end - + EgtRelocateGlob( nSurfId, nGrp) EgtErase( nGrpTmp) return nSurfId @@ -731,17 +763,17 @@ end --------------------------------------------------------------------- -- funzione che restituisce il tipo di controprofilo dell'outline adiacente -local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId, bStart) +local function GetProfileCtrIn( nNearOutlineId, nOutlineId, bStart) local sCtrIn = WIN_CTRIN - local nPrfChange = EgtGetInfo( abs( nPrevOutlineId), WIN_PRF_CHANGE, 'i') or 0 - local nSide = EgtIf( nPrevOutlineId < 0, 1, 2) + local nPrfChange = EgtGetInfo( abs( nNearOutlineId), WIN_PRF_CHANGE, 'i') or 0 + local nSide = EgtIf( nNearOutlineId < 0, 1, 2) -- 1) se è inglesina interna if EgtGetName( nOutlineId) == WIN_SPLIT and EgtGetInfo( nOutlineId, WIN_MUNTINFILL_SIDE, 'i') == WIN_MUNTINFILL_SIDES.IN then -- deve finire contro il fermavetro ( dal lato corretto nel caso di split) oppure contro il bordo interno se finisce contro altra inglesina - if EgtGetName( abs( nPrevOutlineId)) == WIN_SPLIT then - if EgtGetInfo( abs( nPrevOutlineId), WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.MUNTIN_FILL then + if EgtGetName( abs( nNearOutlineId)) == WIN_SPLIT then + if EgtGetInfo( abs( nNearOutlineId), WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.MUNTIN_FILL then sCtrIn = WIN_CTRIN .. WIN_STRIP end else @@ -776,7 +808,7 @@ local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId, bSta else -- per trovare il figlio nell'estremo corretto controllo quale figlio ha l'area in comune con un figlio di PrevOutline local vChildren = EgtGetInfo( nOutlineId, WIN_CHILD_OUTLINE, 'vi') - local vChildrenPrev = EgtGetInfo( abs( nPrevOutlineId), WIN_CHILD_OUTLINE, 'vi') + local vChildrenPrev = EgtGetInfo( abs( nNearOutlineId), WIN_CHILD_OUTLINE, 'vi') for i = 1, #vChildren do if nType then break @@ -802,7 +834,7 @@ local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId, bSta end -- se finisce contro split recupero il controprofilo dal lato corretto ( destro (1) o sinistro (2)) - if EgtGetName( abs( nPrevOutlineId)) == WIN_SPLIT then + if EgtGetName( abs( nNearOutlineId)) == WIN_SPLIT then sCtrIn = sCtrIn .. tostring( nSide) end @@ -1322,7 +1354,8 @@ end local function AdjustProfileDimension( nOutlineId, nProfileId, dDimOld, dDim) local bSplit = ( EgtGetName( nOutlineId) == WIN_SPLIT) - local bPrfChange = ( EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') == WIN_PRF_CHANGE_TYPES.IN) + local nPrfChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL + local bPrfChange = ( nPrfChange & WIN_PRF_CHANGE_TYPES.IN > 0) local bMixedSplit = ( bSplit and EgtGetInfo( nOutlineId, WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.MIXED) local dDeltaDim = dDim - dDimOld @@ -1465,6 +1498,8 @@ end ------------------------------ CALCOLO OUTLINE --------------------------------- ---------------------------------------------------------------------------------- + + ------------------------------ NULL ------------------------------ --------------------------------------------------------------------- local function GetBorderRegions( nSplitId, nCompo, nAreaId) @@ -1509,7 +1544,7 @@ local function AssignSplitName( nCrvId) end --------------------------------------------------------------------- -local function CalculateNullOutline( nCompoOutline, vSplitIds, vChildAreas) +local function CalculateNullAreaOutlines( nCompoOutline, vSplitIds, vChildAreas) local nGrpTmp = EgtGroup( GDB_ID.ROOT) @@ -1576,6 +1611,682 @@ local function CalculateNullOutline( nCompoOutline, vSplitIds, vChildAreas) end +------------------------------ SASH ------------------------------- +--------------------------------------------------------------------- +local function CalculateSashAreaOutlines( nAreaId) + + local nOutlineLayerId = EgtGroup( nAreaId) + EgtSetName( nOutlineLayerId, WIN_OUTLINE) + EgtSetStatus( nOutlineLayerId, GDB_ST.OFF) + + -- calcolo l'outline corrispondente al telaio + local nFrameArea = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*') + local nFrameOutlineLayer = EgtGetFirstNameInGroup( nFrameArea, WIN_OUTLINE) + local vFrameOutlines = EgtGetAllInGroup( nFrameOutlineLayer) + local vFrameOffs = {} + -- calcolo gli offset da applicare ad ogni curva + for i = 1, #vFrameOutlines do + -- recupero il suo profilo per calcolare l'offset + local nProfileId = GetOutlineTheoricProfileId( vFrameOutlines[i]) + local sKey = EgtIf( EgtGetName( vFrameOutlines[i]) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) + local dOverlap = EgtGetInfo( nProfileId, sKey, 'd') + if dOverlap then + local b3Profile = GetProfileLocalBox( nProfileId) + local dRealDim = EgtGetInfo( vFrameOutlines[i], WIN_PART_DIM, 'd') + vFrameOffs[i] = b3Profile:getMin():getX() * dRealDim / b3Profile:getDimX() + dOverlap + end + end + -- costruisco l'outline + for i = 1, #vFrameOutlines do + local nOutlineId = EgtCopyGlob( vFrameOutlines[i], nOutlineLayerId) + EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vFrameOutlines[i]) + -- rimuovo info che non voglio trasferire sull'anta + EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE) + EgtRemoveInfo( nOutlineId, WIN_THRESHOLD) + EgtRemoveInfo( nOutlineId, WIN_PART_DIM) + -- applico l'offset + if vFrameOffs[i] then + EgtOffsetCurve( nOutlineId, vFrameOffs[i]) + else + -- se non ha offset definito è un pezzo che verrà tagliato da uno split ma, affinchè la forma del telaio sia coerente, se è in tangenza con uno dei suoi vicini + -- devo applicare lo stesso offset + local nPrevIdx = EgtIf( i == 1, #vFrameOutlines, i-1) + local nNextIdx = EgtIf( i == #vFrameOutlines, 1, i+1) + if AreSameVectorApprox( EgtSV( vFrameOutlines[i]), EgtEV( vFrameOutlines[nPrevIdx])) then + while not vFrameOffs[nPrevIdx] do + nPrevIdx = EgtIf( nPrevIdx == 1, #vFrameOutlines, nPrevIdx-1) + end + EgtOffsetCurve( nOutlineId, vFrameOffs[nPrevIdx]) + vFrameOffs[i] = vFrameOffs[nPrevIdx] + elseif AreSameVectorApprox( EgtEV( vFrameOutlines[i]), EgtSV( vFrameOutlines[nNextIdx])) then + while not vFrameOffs[nNextIdx] do + nNextIdx = EgtIf( nNextIdx == #vFrameOutlines, 1, nNextIdx+1) + end + EgtOffsetCurve( nOutlineId, vFrameOffs[nNextIdx]) + vFrameOffs[i] = vFrameOffs[nNextIdx] + end + end + end + -- accorcio gli offset + local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) + + + -- 2) taglio con eventuali split + local vSplitIds = {} + local tabSplitCrvName = {} -- associa allo split il nome della curva di outline che da esso deriva + local nParentId = EgtGetParent( nAreaId) + while nParentId ~= nFrameArea do + local nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i') + if nParentType == WIN_AREATYPES.NULL then + local nNullOutlineLay = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE) + local vNullOutlines = EgtGetAllInGroup( nNullOutlineLay) + for i = 1, #vNullOutlines do + local nSou = EgtGetInfo( vNullOutlines[i], WIN_SOU_OUTLINE, 'i') + if EgtGetName( EgtGetParent( EgtGetParent( abs( nSou)))) == WIN_VIRTUAL_AREA then + nSou = EgtGetInfo( abs( nSou), WIN_SOU_OUTLINE, 'i') + end + if EgtGetName( abs( nSou)) == WIN_SPLIT then + table.insert( vSplitIds, nSou) + tabSplitCrvName[abs( nSou)] = EgtGetName( vNullOutlines[i]) + end + end + elseif nParentType == WIN_AREATYPES.SPLIT and EgtGetInfo( nParentId, WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.FRENCH then + -- recupero l'indice dell'anta french dal suo nome + local sAreaName = EgtGetName( nAreaId) + local sAreaIdx = string.sub( sAreaName, string.len( WIN_AREA) + 1, string.len( WIN_AREA) + 1) + local nAreaIdx = tonumber( sAreaIdx) + local nSplitLayerId = EgtGetFirstNameInGroup( nParentId, WIN_SPLIT) + local vFrenchSplits = EgtGetAllInGroup( nSplitLayerId) + -- in base al numero di anta french recupero i french split che la definiscono con il corretto orientamento + if nAreaIdx > 1 then + table.insert( vSplitIds, - vFrenchSplits[nAreaIdx - 1]) + end + if nAreaIdx < #vFrenchSplits + 1 then + table.insert( vSplitIds, vFrenchSplits[nAreaIdx]) + end + end + nParentId = EgtGetParent( nParentId) + end + + if #vSplitIds == 0 then + -- salvo associazioni sou/child sugli outlines + for i = 1, #vCrvs do + local nSouOutlineId = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') + AddInfo( nSouOutlineId, WIN_CHILD_OUTLINE, vCrvs[i]) + end + else + + -- li ordino per id crescente in modo da effettuare i tagli nell'ordine corretto + table.sort( vSplitIds, function ( a, b) return abs( a) < abs( b) end) + + -- creo bordo complessivo dell'outline, salvando le info di SouOutline come temp prop della curva per non perderle + local vSouOutlines = {} + for i = 1, #vCrvs do + vSouOutlines[i] = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') + end + local nCompo = EgtCurveCompo( nOutlineLayerId, vCrvs) + for i = 0, #vCrvs - 1 do + EgtCurveCompoSetTempProp( nCompo, i, vSouOutlines[i+1]) + end + + -- taglio con split + for i = 1, #vSplitIds do + + -- a) creo la curva di outline corrispondente allo split + local nOutlineId = EgtCopy( abs( vSplitIds[i]), nOutlineLayerId) + -- rimuovo info che non voglio trasferire + EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE) + -- verifico orientamento + if vSplitIds[i] < 0 then + EgtInvertCurve( nOutlineId) + end + -- calcolo gli offset + local nProfileId = GetOutlineTheoricProfileId( abs( vSplitIds[i])) + if nProfileId then + local b3Profile = GetProfileLocalBox( nProfileId) + local sKey = EgtIf( tabSplitCrvName[abs( vSplitIds[i])] == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) + local dOverlap = EgtGetInfo( nProfileId, sKey, 'd') + if dOverlap then + local dRealDim = EgtGetInfo( abs( vSplitIds[i]), WIN_PART_DIM, 'd') + local dOffset = abs( b3Profile:getMin():getX()) * dRealDim / b3Profile:getDimX() - dOverlap + EgtOffsetCurve( nOutlineId, - dOffset) + end + else + -- è french split quindi non ha offset + end + + -- b) aggiorno la curva complessiva di outline con la curva appena calcolata + EgtExtendCurveStartByLen( nOutlineId, 1000) + EgtExtendCurveEndByLen( nOutlineId, 1000) + local ptS = EgtIP( nOutlineId, nCompo, EgtSP( nOutlineId)) + local ptE = EgtIP( nOutlineId, nCompo, EgtEP( nOutlineId)) + local dBorderParS = EgtCurveParamAtPoint( nCompo, ptS) + local dBorderParE = EgtCurveParamAtPoint( nCompo, ptE) + EgtTrimCurveStartEndAtParam( nCompo, dBorderParE, dBorderParS) + local dSplitParS = EgtCurveParamAtPoint( nOutlineId, ptS) + local dSplitParE = EgtCurveParamAtPoint( nOutlineId, ptE) + EgtTrimCurveStartEndAtParam( nOutlineId, dSplitParS, dSplitParE) + EgtAddCurveCompoCurve( nCompo, nOutlineId) + local _, dParEnd = EgtCurveDomain( nCompo) + EgtCurveCompoSetTempProp( nCompo, dParEnd - 1, vSplitIds[i]) + end + + -- spezzo la curva di outline nelle sue sottocurve e riassegno le info + local vTempProps = EgtCurveCompoGetTempProp( nCompo) + local nCrv, nCnt = EgtExplodeCurveCompo( nCompo) + for i = 0, nCnt - 1 do + local nOutlineId = nCrv + i + -- assegno le info sou/child + EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vTempProps[i+1]) + if vTempProps[i+1] > 0 then + AddInfo( vTempProps[i+1], WIN_CHILD_OUTLINE, nOutlineId) + else + AddInfo( abs( vTempProps[i+1]), WIN_CHILD_OUTLINE, - nOutlineId) + end + -- sistemo il nome + if EgtGetName( abs( vTempProps[i+1])) == WIN_SPLIT then + -- se deriva da split il nome è salvato nella tabella, se non lo fosse si tratta di un french split e lo calcolo al momento + local sName = tabSplitCrvName[abs( vTempProps[i+1])] + if sName then + EgtSetName( nOutlineId, sName) + else + AssignSplitName( nOutlineId) + end + else + EgtSetName( nOutlineId, EgtGetName( abs( vTempProps[i+1]))) + end + end + + -- riordino in modo da avere il bottom come prima curva + for i = 0, nCnt - 1 do + if EgtGetName( nCrv + i) ~= WIN_BOTTOM then + EgtRelocateGlob( nCrv + i, nOutlineLayerId, GDB_IN.LAST_SON) + else + break + end + end + end + + -- calcolo i profili + local vOutlineCrvs = EgtGetAllInGroup( nOutlineLayerId) + CalcSashProfiles( vOutlineCrvs, nAreaId) + + -- spostamento in z : recupero la quota da un profilo dell'anta + local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) + local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH) + local sSashProfile = EgtGetInfo( vOutlineCrvs[1], WIN_PROFILETYPE) + local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile) + local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd') + EgtMove( vOutlineCrvs, Z_AX() * dSashZOffset) + + return vOutlineCrvs +end + +--------------------------------------------------------------------- +local function VerifySashOutlines( nAreaId, vOutlines) + + -- controlla se i pezzi di un'anta sono validi e se necessitano di gestione speciale nel calcolo dei prev e dei next. Vi sono due tipologie di pezzi che richiedono gestione speciale : + -- a) extra : il pezzo non serve, il suo contributo si limita al trim dei suoi pezzi vicini con il suo bordo out + -- b) special : il pezzo è necessario ma non sufficiente per il trim dei suoi pezzi vicini, che vanno tagliati non solo con il pezzo stesso ma anche tra di loro + -- per distinguere i pezzi extra da special controllo se i semiprofili interni dei pezzi vicini si incontrano in un punto sensato per cui il pezzo risulta superfluo oppure no + + local nGrpTmp1 = EgtGroup( nAreaId) + local nGrpTmp2 = EgtGroup( nAreaId) + + -- recupero i bordi interni ed esterni dei semiprofili in + local vInSemiProfile = {} + local vOutSemiProfile = {} + for i = 1, #vOutlines do + + -- recupero il semiprofilo in + local nProfileId = GetOutlineTheoricProfileId( vOutlines[i]) + local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) + local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT) + local nInId = EgtGetFirstNameInGroup( nProfileId, WIN_IN) + local b3In = EgtGetBBoxRef( nInId, GDB_BB.STANDARD, frSectionFrame) + local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + local dRealDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd') + + vInSemiProfile[i] = EgtCopyGlob( vOutlines[i], nGrpTmp1) + EgtSetInfo( vInSemiProfile[i], 'SouIdx', i) + -- se non è possibile calcolare l'interno ( e.g. arco con raggio inferiore alla sua dimensione) il pezzo è sicuramente extra ma considero comunque le sue curve nel fare i conti + -- per non sfalsare gli indici + if not EgtOffsetCurve( vInSemiProfile[i], b3In:getMin():getX() * dRealDim / dDimStd) then + EgtSetInfo( vOutlines[i], WIN_EXTRA_CRV, true) + end + + vOutSemiProfile[i] = EgtCopyGlob( vOutlines[i], nGrpTmp2) + EgtOffsetCurve( vOutSemiProfile[i], b3In:getMax():getX() * dRealDim / dDimStd) + EgtSetInfo( vOutSemiProfile[i], 'SouIdx', i) + end + + local _, vExtraIn = TrimOrderedCurves( vInSemiProfile, false) + -- se nessun bordo più interno scompare allora tutti i pezzi sono standard + if #vExtraIn == 0 then + EgtErase( nGrpTmp1) + EgtErase( nGrpTmp2) + return + end + + local _, vExtraOut = TrimOrderedCurves( vOutSemiProfile, false) + -- se il bordo esterno del suo profilo in scompare i suoi vicini si incontrano in modo sensato quindi il pezzo è sicuramente superfluo + for i = 1, #vExtraOut do + local nIdx = EgtGetInfo( vExtraOut[i], 'SouIdx', 'i') + EgtSetInfo( vOutlines[nIdx], WIN_EXTRA_CRV, true) + end + + -- analizzo i tratti con gestione speciale consecutivi insieme + local nOldId + local vExtraInGrps = {} + for i = 1, #vExtraIn do + local nIdx = EgtGetInfo( vExtraIn[i], 'SouIdx', 'i') + if not EgtGetInfo( vOutlines[nIdx], WIN_EXTRA_CRV, 'b') then + if not nOldId or EgtGetNext( nOldId) ~= vExtraIn[i] then + table.insert( vExtraInGrps, { vExtraIn[i]}) + else + table.insert( vExtraInGrps[#vExtraInGrps], vExtraIn[i]) + end + nOldId = vExtraIn[i] + end + end + + for i = 1, #vExtraInGrps do + + -- calcolo il punto di incontro dei semiprofili interni dei due pezzi vicini validi + local nIdx1 = EgtGetInfo( vExtraInGrps[i][1], 'SouIdx', 'i') + local nPrevIdx = EgtIf( nIdx1 == 1, #vOutlines, nIdx1-1) + while EgtGetInfo( vOutlines[nPrevIdx], WIN_EXTRA_CRV, 'b') do + nPrevIdx = EgtIf( nPrevIdx == 1, #vOutlines, nPrevIdx-1) + end + local nIdx2 = EgtGetInfo( vExtraInGrps[i][#vExtraInGrps[i]], 'SouIdx', 'i') + local nNextIdx = EgtIf( nIdx2 == #vOutlines, 1, nIdx2+1) + while EgtGetInfo( vOutlines[nNextIdx], WIN_EXTRA_CRV, 'b') do + nNextIdx = EgtIf( nNextIdx == #vOutlines, 1, nNextIdx+1) + end + local nPrevOut = vOutSemiProfile[nPrevIdx] + local nNextOut = vOutSemiProfile[nNextIdx] + local ptInters = FindIntersectionPoint( nPrevOut, nNextOut, EgtEP( nPrevOut)) + + -- ricavo le curva che delimita la regione valida per l'intersezione dei semiprofili dei pezzi vicini + local vCurrOutlines = {} + for j = 1, #vExtraInGrps[i] do + local nIdx = EgtGetInfo( vExtraInGrps[i][j], 'SouIdx', 'i') + vCurrOutlines[j] = vOutlines[nIdx] + end + local nCompoOutline = EgtCurveCompo( nGrpTmp1, vCurrOutlines, false) + local nProfileId = GetOutlineTheoricProfileId( vCurrOutlines[1]) + local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') + local dRealDim = EgtGetInfo( vCurrOutlines[1], WIN_PART_DIM, 'd') + local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) + local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT) + local nCPId = EgtGetFirstNameInGroup( nProfileId, WIN_OUT) + local b3CP = EgtGetBBoxRef( nCPId, GDB_BB.STANDARD, frSectionFrame) + local nRefCrv = EgtOffsetCurveAdv( nCompoOutline, b3CP:getMin():getX() * dRealDim / dDimStd) + local _, _, nSide = EgtPointCurveDistSide( ptInters, nRefCrv, Z_AX()) + + for j = 1, #vCurrOutlines do + -- se il punto di intersezione cade nella regione valida il pezzo è extra altrimenti è special + if nSide == -1 then + EgtSetInfo( vCurrOutlines[j], WIN_EXTRA_CRV, true) + else + EgtSetInfo( vCurrOutlines[j], WIN_SPECIAL_CRV, true) + end + end + end + + EgtErase( nGrpTmp1) + EgtErase( nGrpTmp2) +end + +--------------------------------------------------------------------- +-- funzione che identifica la forma dell'anta/gruppo di ante +local function IdentifySashShape( nAreaId, vOutlines) + + local nCompoId = EgtCurveCompo( nAreaId, vOutlines, false) + + -- verifico se trapezio + local bTrap, ptOrig, vtB1, vtE1, vtB2 = EgtCurveIsATrapezoid( nCompoId) + if bTrap then + -- verifico se rettangolo controllando se lati sono paralleli + local vtE2 = vtB1 + vtE1 - vtB2 + if AreSameOrOppositeVectorApprox( vtE1, vtE2) then + EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.RECT) + else + EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.TRAP) + end + + else + -- verifico se cerchio + local bCircle = EgtCurveIsACircle( nCompoId) + if bCircle then + EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.CIRCLE) + + -- verifico se forma con arco + elseif #vOutlines == 4 and EgtGetType( vOutlines[3]) == GDB_TY.CRV_ARC then + local dAngCenter = EgtArcAngCenter( vOutlines[3]) + if abs( dAngCenter - 180) < GEO.EPS_SMALL then + EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.ROUND_ARC) + else + if abs( EgtCurveLength( vOutlines[2]) - EgtCurveLength( vOutlines[4])) < GEO.EPS_SMALL then + EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEGMENTAL_ARC) + else + -- verifico se metà di arco a tutto sesto o ribassato + if AreSameVectorApprox( EgtEV( vOutlines[2]), EgtSV( vOutlines[3])) or AreSameVectorApprox( EgtEV( vOutlines[3]), EgtSV( vOutlines[4])) then + EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEMI_ROUND_ARC) + else + EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEMI_SEGMENTAL_ARC) + end + end + end + else + EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.GENERIC) + end + end + + EgtErase( nCompoId) +end + +--------------------------------------------------------------------- +-- funzione che disegna l'apertura dell'anta +local function DrawOpening( nAreaId, vOutlines) + + local nOpeningType = EgtGetInfo( nAreaId, WIN_OPENING_TYPE, 'i') + if nOpeningType == WIN_OPENING_TYPES.NULL then + return + end + + -- creo gruppo per aperture + local nOpeningLayId = EgtGroup( nAreaId) + EgtSetName( nOpeningLayId, WIN_SASH_OPENING) + + -- verifico se anta ricevente per impostare tratteggio + local nFactor = 7 + local nPattern = 0xAAAA + local nType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i') + local bStippled = ( nType == WIN_SASHTYPES.INACTIVE or nType == WIN_SASHTYPES.INACTIVE_IN or nType == WIN_SASHTYPES.INACTIVE_OUT) + + -- calcolo la curva di riferimento per il disegno dell'apertura + -- TODO gestire caso di triangolo + if #vOutlines == 3 then + return + end + local vCrvs = {} + for i = 1, #vOutlines do + local nCrv = EgtCopyGlob( vOutlines[i], nOpeningLayId) + table.insert( vCrvs, nCrv) + local nProfileId = GetOutlineTheoricProfileId( vOutlines[i], true) + local dRealDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd') + local dRailOffs = 0 + if EgtGetName( nProfileId) == WIN_FILL_RAIL then + local nBottomRail = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL, 'i') + dRailOffs = CalcRailOffset( vOutlines[i], nProfileId, nBottomRail) + local vBottomRailDims = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd') + dRealDim = vBottomRailDims[#vBottomRailDims] + end + local b3Profile = GetProfileLocalBox( nProfileId) + local dOffs = b3Profile:getMin():getX() * dRealDim / b3Profile:getDimX() - dRailOffs + EgtOffsetCurve( nCrv, dOffs) + end + vCrvs = TrimOrderedCurves( vCrvs, true) + local nGuideId = EgtCurveCompo( nOpeningLayId, vCrvs) + local _, dParE = EgtCurveDomain( nGuideId) + + -- ribalta + if nOpeningType == WIN_OPENING_TYPES.TILTONLY_TOP or nOpeningType == WIN_OPENING_TYPES.TILTTURN_LEFT or nOpeningType == WIN_OPENING_TYPES.TILTTURN_RIGHT then + -- ricavo il punto sul top + local ptMid = EgtUP( nGuideId, 2.5) + if not EgtCurveIsARectangle( nGuideId) then + -- per maggiore simmetria ricavo il punto sul top in corrispondenza del punto medio del bottom + local ptTest = EgtUP( nGuideId, 0.5) + local nLineTest = EgtLinePVL( nOpeningLayId, ptTest + Y_AX(), Y_AX(), 10000) + ptMid = EgtIP( nGuideId, nLineTest, ORIG()) + EgtErase( nLineTest) + end + EgtCurveCompoFromPoints( nOpeningLayId, { EgtSP( nGuideId), ptMid, EgtUP( nGuideId, 1)}) + elseif nOpeningType == WIN_OPENING_TYPES.TILTONLY_BOTTOM then + -- ricavo il punto sul bottom + local ptMid = EgtUP( nGuideId, 0.5) + EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 2), ptMid, EgtUP( nGuideId, dParE - 1)}) + end + + -- altre tipologie + if nOpeningType == WIN_OPENING_TYPES.TILTTURN_LEFT or nOpeningType == WIN_OPENING_TYPES.TURNONLY_LEFT then + -- battente sx + local dLenRight = EgtCurveCompoLength( nGuideId, 1) + local dLenLeft = EgtCurveCompoLength( nGuideId, dParE - 1) + local dParMid = 1.5 + -- se lato sinistro è il più corto, prendo sul destro il corrispondente del suo punto medio + if dLenLeft < dLenRight - GEO.EPS_SMALL then + dParMid = EgtCurveParamAtLength( nGuideId, EgtCurveCompoLength( nGuideId, 0) + dLenLeft * 0.5) + end + local nCrv = EgtCurveCompoFromPoints( nOpeningLayId, { EgtSP( nGuideId), EgtUP( nGuideId, dParMid), EgtUP( nGuideId, dParE - 1)}) + -- tratteggio + if bStippled then + EgtSetStipple( nCrv, nFactor, nPattern) + end + + elseif nOpeningType == WIN_OPENING_TYPES.TILTTURN_RIGHT or nOpeningType == WIN_OPENING_TYPES.TURNONLY_RIGHT then + -- battente dx + local dLenRight = EgtCurveCompoLength( nGuideId, 1) + local dLenLeft = EgtCurveCompoLength( nGuideId, dParE - 1) + local dParMid = dParE - 0.5 + -- se lato destro è il più corto, prendo sul sinistro il corrispondente del suo punto medio + if dLenRight < dLenLeft - GEO.EPS_SMALL then + dParMid = EgtCurveParamAtLength( nGuideId, EgtCurveLength( nGuideId) - dLenRight * 0.5) + end + local nCrv = EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 1), EgtUP( nGuideId, dParMid), EgtUP( nGuideId, 2)}) + -- tratteggio + if bStippled then + EgtSetStipple( nCrv, nFactor, nPattern) + end + + elseif nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT or + nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_RIGHT then + -- scorrevole e alzante scorrevole ( solo forma rettangolare) + local bRight = ( nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT or nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_RIGHT) + local dLen0 = EgtCurveCompoLength( nGuideId, 0) + local dLen1 = EgtCurveCompoLength( nGuideId, 1) + local dCoeff = 0.15 + local ptS = EgtUP( nGuideId, 1.5) - dCoeff * dLen0 * X_AX() + local ptE = EgtUP( nGuideId, dParE - 0.5) + dCoeff * dLen0 * X_AX() + if bRight then + ptS, ptE = ptE, ptS + end + local nCompo = EgtCurveCompoFromPoints( nOpeningLayId, { ptS, ptE}) + if nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT then + EgtAddCurveCompoLine( nCompo, ptS - dCoeff * dLen1 * Y_AX(), false) + end + local dAng = EgtIf( bRight, 135, 45) + EgtLinePDL( nOpeningLayId, ptE, dAng, dCoeff * dLen0) + EgtLinePDL( nOpeningLayId, ptE, - dAng, dCoeff * dLen0) + + elseif nOpeningType == WIN_OPENING_TYPES.FIXED then + -- nessun disegno + + elseif nOpeningType == WIN_OPENING_TYPES.PIVOT then + -- bilico rettangolare + local nCompo = EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 0.5), EgtUP( nGuideId, 1.5), EgtUP( nGuideId, 2.5), EgtUP( nGuideId, 3.5)}) + EgtCloseCurveCompo( nCompo) + -- TODO oblò + end + + EgtErase( nGuideId) +end + + +------------------------------ FILL ------------------------------- +--------------------------------------------------------------------- +local function CalculateFillAreaOutlines( nAreaId) + + local nOutlineLayerId = EgtGroup( nAreaId) + EgtSetName( nOutlineLayerId, WIN_OUTLINE) + EgtSetStatus( nOutlineLayerId, GDB_ST.OFF) + + -- recupero area parent di tipo telaio/anta che la contiene + local nParentArea = EgtGetParent( nAreaId) + local nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i') + while nAreaType ~= WIN_AREATYPES.FRAME and nAreaType ~= WIN_AREATYPES.SASH do + nParentArea = EgtGetParent( nParentArea) + nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i') + end + + -- 1) calcolo l'area complessiva di fill definita dal suo parent + local nParentOutlineLayer = EgtGetFirstNameInGroup( nParentArea, WIN_OUTLINE) + local dDeltaZ = 0 + local vParentOutlines = EgtGetAllInGroup( nParentOutlineLayer) + local vParentOffs = {} + -- calcolo gli offset + for i = 1, #vParentOutlines do + -- recupero il suo profilo per calcolare l'offset perpendicolare + local nParentProfileId = GetOutlineTheoricProfileId( vParentOutlines[i], true) + local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd') + if dOverlap then + local dRealDim = EgtGetInfo( vParentOutlines[i], WIN_PART_DIM, 'd') + -- verifico se contributo per bottomrail + local dRailOffs = 0 + if EgtGetName( nParentProfileId) == WIN_FILL_RAIL then + local nBottomRail = EgtGetInfo( vParentOutlines[i], WIN_BOTTOMRAIL, 'i') + dRailOffs = CalcRailOffset( vParentOutlines[i], nParentProfileId, nBottomRail) + local vBottomRailDims = EgtGetInfo( vParentOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd') + dRealDim = vBottomRailDims[#vBottomRailDims] + end + local b3FrameProfile = GetProfileLocalBox( nParentProfileId) + local dDimRef = b3FrameProfile:getMin():getX() * dRealDim / b3FrameProfile:getDimX() + vParentOffs[i] = abs( dDimRef) - dOverlap + dRailOffs + -- movimento in z + if dDeltaZ < GEO.EPS_SMALL then + dDeltaZ = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd') + end + end + end + -- creo le curve di outlines + for i = 1, #vParentOutlines do + -- copio la curva di outline del parent + local nOutlineId = EgtCopy( vParentOutlines[i], nOutlineLayerId) + EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vParentOutlines[i]) + -- applico offset + if vParentOffs[i] then + EgtOffsetCurve( nOutlineId, - vParentOffs[i]) + else + -- se non ha offset definito è un pezzo che verrà tagliato da uno split ma, affinchè la forma del telaio sia coerente, devo applicare lo stesso offset a curve + -- che sono in tangenza + local nPrevIdx = EgtIf( i == 1, #vParentOutlines, i-1) + local nNextIdx = EgtIf( i == #vParentOutlines, 1, i+1) + if AreSameVectorApprox( EgtSV( vParentOutlines[i]), EgtEV( vParentOutlines[nPrevIdx])) then + while not vParentOffs[nPrevIdx] do + nPrevIdx = EgtIf( nPrevIdx == 1, #vParentOutlines, nPrevIdx-1) + end + EgtOffsetCurve( nOutlineId, - vParentOffs[nPrevIdx]) + vParentOffs[i] = vParentOffs[nPrevIdx] + elseif AreSameVectorApprox( EgtEV( vParentOutlines[i]), EgtSV( vParentOutlines[nNextIdx])) then + while not vParentOffs[nNextIdx] do + nNextIdx = EgtIf( nNextIdx == #vParentOutlines, 1, nNextIdx+1) + end + EgtOffsetCurve( nOutlineId, - vParentOffs[nNextIdx]) + vParentOffs[i] = vParentOffs[nNextIdx] + end + end + end + -- accorcio gli offset + local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) + -- applico spostamento verticale + EgtMove( vCrvs, Z_AX() * dDeltaZ) + + + -- 2) taglio con split + local nParentType = EgtGetInfo( EgtGetParent( nAreaId), WIN_AREATYPE, 'i') + if nParentType ~= WIN_AREATYPES.NULL then + -- salvo associazioni sou/child + for i = 1, #vCrvs do + local nSouOutlineId = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') + AddInfo( nSouOutlineId, WIN_CHILD_OUTLINE, vCrvs[i]) + end + return + end + + -- creo bordo complessivo dell'outline, salvando le info come temp prop della curva per non perderle + local vSouOutlines = {} + for i = 1, #vCrvs do + vSouOutlines[i] = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') + end + local nCompo = EgtCurveCompo( nOutlineLayerId, vCrvs) + for i = 0, #vCrvs - 1 do + EgtCurveCompoSetTempProp( nCompo, i, vSouOutlines[i+1]) + end + + -- recupero gli split che definiscono l'area fill cercando gli split in tutte le aree parent di tipo null + local vSplitIds = {} + local nParentId = EgtGetParent( nAreaId) + while nParentId ~= nParentArea do + local nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i') + if nParentType == WIN_AREATYPES.NULL then + local nNullOutlineLay = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE) + local vNullOutlines = EgtGetAllInGroup( nNullOutlineLay) + for i = 1, #vNullOutlines do + local nSou = EgtGetInfo( vNullOutlines[i], WIN_SOU_OUTLINE, 'i') + if EgtGetName( EgtGetParent( EgtGetParent( abs( nSou)))) == WIN_VIRTUAL_AREA then + nSou = EgtGetInfo( abs( nSou), WIN_SOU_OUTLINE, 'i') + end + if EgtGetName( abs( nSou)) == WIN_SPLIT then + table.insert( vSplitIds, nSou) + end + end + end + nParentId = EgtGetParent( nParentId) + end + + -- li ordino per id crescente in modo da effettuare i tagli nell'ordine corretto + table.sort( vSplitIds, function ( a, b) return abs( a) < abs( b) end) + + for i = 1, #vSplitIds do + + -- creo la curva di outline corrispondente allo split + local nOutlineId = EgtCopy( abs( vSplitIds[i]), nOutlineLayerId) + if vSplitIds[i] < 0 then + EgtInvertCurve( nOutlineId) + end + -- calcolo gli offset + local nProfileId = GetOutlineTheoricProfileId( abs( vSplitIds[i]), true) + local b3Profile = GetProfileLocalBox( nProfileId) + local dOverlap = EgtGetInfo( nProfileId, WIN_FILLOVERLAP, 'd') + if dOverlap then + local dDimRef = EgtIf( vSplitIds[i] < 0, b3Profile:getMax():getX(), b3Profile:getMin():getX()) + local dRealDim = EgtGetInfo( abs( vSplitIds[i]), WIN_PART_DIM, 'd') + local dOffs = abs( dDimRef) * dRealDim / b3Profile:getDimX() - dOverlap + EgtOffsetCurve( nOutlineId, - dOffs) + end + -- movimento in z + local dFillZOffset = EgtGetInfo( nProfileId, WIN_FILLDELTA, 'd') + EgtMove( nOutlineId, Z_AX() * dFillZOffset) + + -- aggiorno la curva complessiva di outline con la curva appena calcolata + local ptS = EgtIP( nOutlineId, nCompo, EgtSP( nOutlineId)) + local ptE = EgtIP( nOutlineId, nCompo, EgtEP( nOutlineId)) + local dBorderParS = EgtCurveParamAtPoint( nCompo, ptS) + local dBorderParE = EgtCurveParamAtPoint( nCompo, ptE) + EgtTrimCurveStartEndAtParam( nCompo, dBorderParE, dBorderParS) + local dSplitParS = EgtCurveParamAtPoint( nOutlineId, ptS) + local dSplitParE = EgtCurveParamAtPoint( nOutlineId, ptE) + EgtTrimCurveStartEndAtParam( nOutlineId, dSplitParS, dSplitParE) + EgtAddCurveCompoCurve( nCompo, nOutlineId) + local _, dParEnd = EgtCurveDomain( nCompo) + EgtCurveCompoSetTempProp( nCompo, dParEnd - 1, vSplitIds[i]) + end + + -- spezzo la curva di outline nelle sue sottocurve e riassegno le info + local vTempProps = EgtCurveCompoGetTempProp( nCompo) + local nCrv, nCnt = EgtExplodeCurveCompo( nCompo) + for i = 0, nCnt - 1 do + EgtSetInfo( nCrv + i, WIN_SOU_OUTLINE, vTempProps[i+1]) + if vTempProps[i+1] > 0 then + AddInfo( vTempProps[i+1], WIN_CHILD_OUTLINE, nCrv + i) + else + AddInfo( abs( vTempProps[i+1]), WIN_CHILD_OUTLINE, - ( nCrv + i)) + end + end +end + + ------------------------------ SPLIT ------------------------------ --------------------------------------------------------------------- -- funzione che adatta la curva di split al bordo @@ -1883,18 +2594,15 @@ local function CalcSplitPositionOffsets( nAreaId, nAreaInfoId, vSplitIds, nSplit end --------------------------------------------------------------------- -local function CalculateSplitOutline( nAreaId, vSplitIds) +local function AdjustSplitOutlines( nAreaId, vSplitIds, nOutlineLayerId, nSplitType) - -- recupero l'outline e creo composita del bordo - local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) + -- creo composita del bordo di outline local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId) local nOutlineCompo = EgtCurveCompo( nAreaId, vOutlineIds, false) for i = 1, #vOutlineIds do EgtCurveCompoSetTempProp( nOutlineCompo, i - 1, vOutlineIds[i]) end - local nSplitType = EgtGetInfo( vSplitIds[1], WIN_SPLITTYPE, 'i') - -- assegno le dimensioni if nSplitType ~= WIN_SPLITTYPES.FRENCH then local vSplitDim = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {} @@ -1918,14 +2626,17 @@ local function CalculateSplitOutline( nAreaId, vSplitIds) -- creo l'outline delle aree figlie di tipo null if nSplitType ~= WIN_SPLITTYPES.FRENCH then local vChildAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') - CalculateNullOutline( nOutlineCompo, vSplitIds, vChildAreas) + CalculateNullAreaOutlines( nOutlineCompo, vSplitIds, vChildAreas) + else + -- se french split identifico la forma del gruppo di ante + IdentifySashShape( nAreaId, vOutlineIds) end - + EgtErase( nOutlineCompo) end --------------------------------------------------------------------- -local function CalculateGridSplitOutline( nAreaId, vSplitIds) +local function AdjustGridSplitOutlines( nAreaId, vSplitIds) local vAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') local vVirtualAreas = EgtGetNameInGroup( nAreaId, WIN_VIRTUAL_AREA) @@ -1992,834 +2703,317 @@ local function CalculateGridSplitOutline( nAreaId, vSplitIds) end -- creo gli outline delle aree figlie ( i.e. aree virtuali per split principale, sottoaree di ordine i-esimo per split secondari di ordine i-esimo) - CalculateNullOutline( nOutlineCompo, tabGrid[i], EgtIf( i == 0, vVirtualAreas, tabAreas[i])) + CalculateNullAreaOutlines( nOutlineCompo, tabGrid[i], EgtIf( i == 0, vVirtualAreas, tabAreas[i])) EgtErase( nOutlineCompo) end end - ------------------------------- SASH ------------------------------- --------------------------------------------------------------------- --- funzione che disegna l'apertura dell'anta -local function DrawOpening( nAreaId) - - local nOpeningType = EgtGetInfo( nAreaId, WIN_OPENING_TYPE, 'i') - if nOpeningType == WIN_OPENING_TYPES.NULL then - return - end - - -- creo gruppo per aperture - local nOpeningLayId = EgtGroup( nAreaId) - EgtSetName( nOpeningLayId, WIN_SASH_OPENING) +local function CalcSplitAreaOutlines( nAreaId) - -- verifico se anta ricevente per impostare tratteggio - local nFactor = 7 - local nPattern = 0xAAAA - local nType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i') - local bStippled = ( nType == WIN_SASHTYPES.INACTIVE or nType == WIN_SASHTYPES.INACTIVE_IN or nType == WIN_SASHTYPES.INACTIVE_OUT) - - -- calcolo la curva di riferimento per il disegno dell'apertura - local nOutlineLayId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) - local vOutlines = EgtGetAllInGroup( nOutlineLayId) - -- TODO gestire caso di triangolo - if #vOutlines == 3 then - return - end - local vCrvs = {} - for i = 1, #vOutlines do - local nCrv = EgtCopyGlob( vOutlines[i], nOpeningLayId) - table.insert( vCrvs, nCrv) - local nProfileId = GetOutlineTheoricProfileId( vOutlines[i], true) - local dRealDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd') - local dRailOffs = 0 - if EgtGetName( nProfileId) == WIN_FILL_RAIL then - local nBottomRail = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL, 'i') - dRailOffs = CalcRailOffset( vOutlines[i], nProfileId, nBottomRail) - local vBottomRailDims = EgtGetInfo( vOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd') - dRealDim = vBottomRailDims[#vBottomRailDims] - end - local b3Profile = GetProfileLocalBox( nProfileId) - local dOffs = b3Profile:getMin():getX() * dRealDim / b3Profile:getDimX() - dRailOffs - EgtOffsetCurve( nCrv, dOffs) - end - vCrvs = TrimOrderedCurves( vCrvs, true) - local nGuideId = EgtCurveCompo( nOpeningLayId, vCrvs) - local _, dParE = EgtCurveDomain( nGuideId) - - -- ribalta - if nOpeningType == WIN_OPENING_TYPES.TILTONLY_TOP or nOpeningType == WIN_OPENING_TYPES.TILTTURN_LEFT or nOpeningType == WIN_OPENING_TYPES.TILTTURN_RIGHT then - -- ricavo il punto sul top - local ptMid = EgtUP( nGuideId, 2.5) - if not EgtCurveIsARectangle( nGuideId) then - -- per maggiore simmetria ricavo il punto sul top in corrispondenza del punto medio del bottom - local ptTest = EgtUP( nGuideId, 0.5) - local nLineTest = EgtLinePVL( nOpeningLayId, ptTest + Y_AX(), Y_AX(), 10000) - ptMid = EgtIP( nGuideId, nLineTest, ORIG()) - EgtErase( nLineTest) - end - EgtCurveCompoFromPoints( nOpeningLayId, { EgtSP( nGuideId), ptMid, EgtUP( nGuideId, 1)}) - elseif nOpeningType == WIN_OPENING_TYPES.TILTONLY_BOTTOM then - -- ricavo il punto sul bottom - local ptMid = EgtUP( nGuideId, 0.5) - EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 2), ptMid, EgtUP( nGuideId, dParE - 1)}) - end - - -- altre tipologie - if nOpeningType == WIN_OPENING_TYPES.TILTTURN_LEFT or nOpeningType == WIN_OPENING_TYPES.TURNONLY_LEFT then - -- battente sx - local dLenRight = EgtCurveCompoLength( nGuideId, 1) - local dLenLeft = EgtCurveCompoLength( nGuideId, dParE - 1) - local dParMid = 1.5 - -- se lato sinistro è il più corto, prendo sul destro il corrispondente del suo punto medio - if dLenLeft < dLenRight - GEO.EPS_SMALL then - dParMid = EgtCurveParamAtLength( nGuideId, EgtCurveCompoLength( nGuideId, 0) + dLenLeft * 0.5) - end - local nCrv = EgtCurveCompoFromPoints( nOpeningLayId, { EgtSP( nGuideId), EgtUP( nGuideId, dParMid), EgtUP( nGuideId, dParE - 1)}) - -- tratteggio - if bStippled then - EgtSetStipple( nCrv, nFactor, nPattern) - end - - elseif nOpeningType == WIN_OPENING_TYPES.TILTTURN_RIGHT or nOpeningType == WIN_OPENING_TYPES.TURNONLY_RIGHT then - -- battente dx - local dLenRight = EgtCurveCompoLength( nGuideId, 1) - local dLenLeft = EgtCurveCompoLength( nGuideId, dParE - 1) - local dParMid = dParE - 0.5 - -- se lato destro è il più corto, prendo sul sinistro il corrispondente del suo punto medio - if dLenRight < dLenLeft - GEO.EPS_SMALL then - dParMid = EgtCurveParamAtLength( nGuideId, EgtCurveLength( nGuideId) - dLenRight * 0.5) - end - local nCrv = EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 1), EgtUP( nGuideId, dParMid), EgtUP( nGuideId, 2)}) - -- tratteggio - if bStippled then - EgtSetStipple( nCrv, nFactor, nPattern) - end - - elseif nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT or - nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_RIGHT then - -- scorrevole e alzante scorrevole ( solo forma rettangolare) - local bRight = ( nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT or nOpeningType == WIN_OPENING_TYPES.LIFTSLIDE_RIGHT) - local dLen0 = EgtCurveCompoLength( nGuideId, 0) - local dLen1 = EgtCurveCompoLength( nGuideId, 1) - local dCoeff = 0.15 - local ptS = EgtUP( nGuideId, 1.5) - dCoeff * dLen0 * X_AX() - local ptE = EgtUP( nGuideId, dParE - 0.5) + dCoeff * dLen0 * X_AX() - if bRight then - ptS, ptE = ptE, ptS - end - local nCompo = EgtCurveCompoFromPoints( nOpeningLayId, { ptS, ptE}) - if nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_LEFT or nOpeningType == WIN_OPENING_TYPES.COPLANARSLIDE_RIGHT then - EgtAddCurveCompoLine( nCompo, ptS - dCoeff * dLen1 * Y_AX(), false) - end - local dAng = EgtIf( bRight, 135, 45) - EgtLinePDL( nOpeningLayId, ptE, dAng, dCoeff * dLen0) - EgtLinePDL( nOpeningLayId, ptE, - dAng, dCoeff * dLen0) - - elseif nOpeningType == WIN_OPENING_TYPES.FIXED then - -- nessun disegno - - elseif nOpeningType == WIN_OPENING_TYPES.PIVOT then - -- bilico rettangolare - local nCompo = EgtCurveCompoFromPoints( nOpeningLayId, { EgtUP( nGuideId, 0.5), EgtUP( nGuideId, 1.5), EgtUP( nGuideId, 2.5), EgtUP( nGuideId, 3.5)}) - EgtCloseCurveCompo( nCompo) - -- TODO oblò - end - - EgtErase( nGuideId) -end - ---------------------------------------------------------------------- --- funzione che identifica la forma dell'anta/gruppo di ante -local function IdentifySashShape( nAreaId, nOutlineLayerId) - - local vOutlines = EgtGetAllInGroup( nOutlineLayerId) - local nCompoId = EgtCurveCompo( nOutlineLayerId, vOutlines, false) - - -- verifico se trapezio - local bTrap, ptOrig, vtB1, vtE1, vtB2 = EgtCurveIsATrapezoid( nCompoId) - if bTrap then - -- verifico se rettangolo controllando se lati sono paralleli - local vtE2 = vtB1 + vtE1 - vtB2 - if AreSameOrOppositeVectorApprox( vtE1, vtE2) then - EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.RECT) - else - EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.TRAP) - end - - else - -- verifico se cerchio - local bCircle = EgtCurveIsACircle( nCompoId) - if bCircle then - EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.CIRCLE) - - -- verifico se forma con arco - elseif #vOutlines == 4 and EgtGetType( vOutlines[3]) == GDB_TY.CRV_ARC then - local dAngCenter = EgtArcAngCenter( vOutlines[3]) - if abs( dAngCenter - 180) < GEO.EPS_SMALL then - EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.ROUND_ARC) - else - if abs( EgtCurveLength( vOutlines[2]) - EgtCurveLength( vOutlines[4])) < GEO.EPS_SMALL then - EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEGMENTAL_ARC) - else - -- verifico se metà di arco a tutto sesto o ribassato - if AreSameVectorApprox( EgtEV( vOutlines[2]), EgtSV( vOutlines[3])) or AreSameVectorApprox( EgtEV( vOutlines[3]), EgtSV( vOutlines[4])) then - EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEMI_ROUND_ARC) - else - EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.SEMI_SEGMENTAL_ARC) - end - end - end - else - EgtSetInfo( nAreaId, WIN_SASH_SHAPE, WIN_SASH_SHAPES.GENERIC) - end - end - - EgtErase( nCompoId) -end - ---------------------------------------------------------------------- -local function CalculateSashOutline( nAreaId, nAreaLayerId, nOutlineLayerId) - - -- calcolo l'outline corrispondente al telaio - local nFrameArea = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*') - local nFrameOutlineLayer = EgtGetFirstNameInGroup( nFrameArea, WIN_OUTLINE) - local vFrameOutlines = EgtGetAllInGroup( nFrameOutlineLayer) - local vFrameOffs = {} - -- calcolo gli offset da applicare ad ogni curva - for i = 1, #vFrameOutlines do - -- recupero il suo profilo per calcolare l'offset - local nProfileId = GetOutlineTheoricProfileId( vFrameOutlines[i]) - local sKey = EgtIf( EgtGetName( vFrameOutlines[i]) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) - local dOverlap = EgtGetInfo( nProfileId, sKey, 'd') - if dOverlap then - local b3Profile = GetProfileLocalBox( nProfileId) - local dRealDim = EgtGetInfo( vFrameOutlines[i], WIN_PART_DIM, 'd') - vFrameOffs[i] = b3Profile:getMin():getX() * dRealDim / b3Profile:getDimX() + dOverlap - end - end - -- costruisco l'outline - for i = 1, #vFrameOutlines do - local nOutlineId = EgtCopyGlob( vFrameOutlines[i], nOutlineLayerId) - EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vFrameOutlines[i]) - -- rimuovo info che non voglio trasferire sull'anta - EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE) - EgtRemoveInfo( nOutlineId, WIN_THRESHOLD) - EgtRemoveInfo( nOutlineId, WIN_PART_DIM) - -- applico l'offset - if vFrameOffs[i] then - EgtOffsetCurve( nOutlineId, vFrameOffs[i]) - else - -- se non ha offset definito è un pezzo che verrà tagliato da uno split ma, affinchè la forma del telaio sia coerente, se è in tangenza con uno dei suoi vicini - -- devo applicare lo stesso offset - local nPrevIdx = EgtIf( i == 1, #vFrameOutlines, i-1) - local nNextIdx = EgtIf( i == #vFrameOutlines, 1, i+1) - if AreSameVectorApprox( EgtSV( vFrameOutlines[i]), EgtEV( vFrameOutlines[nPrevIdx])) then - while not vFrameOffs[nPrevIdx] do - nPrevIdx = EgtIf( nPrevIdx == 1, #vFrameOutlines, nPrevIdx-1) - end - EgtOffsetCurve( nOutlineId, vFrameOffs[nPrevIdx]) - vFrameOffs[i] = vFrameOffs[nPrevIdx] - elseif AreSameVectorApprox( EgtEV( vFrameOutlines[i]), EgtSV( vFrameOutlines[nNextIdx])) then - while not vFrameOffs[nNextIdx] do - nNextIdx = EgtIf( nNextIdx == #vFrameOutlines, 1, nNextIdx+1) - end - EgtOffsetCurve( nOutlineId, vFrameOffs[nNextIdx]) - vFrameOffs[i] = vFrameOffs[nNextIdx] - end - end - end - -- accorcio gli offset - local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) - - - -- 2) taglio con eventuali split - local vSplitIds = {} - local tabSplitCrvName = {} -- associa allo split il nome della curva di outline che da esso deriva + -- a) outline + local nOutlineLayerId = EgtGroup( nAreaId) + EgtSetName( nOutlineLayerId, WIN_OUTLINE) + EgtSetStatus( nOutlineLayerId, GDB_ST.OFF) + -- è la copia del parent outline local nParentId = EgtGetParent( nAreaId) - while nParentId ~= nFrameArea do - local nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i') - if nParentType == WIN_AREATYPES.NULL then - local nNullOutlineLay = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE) - local vNullOutlines = EgtGetAllInGroup( nNullOutlineLay) - for i = 1, #vNullOutlines do - local nSou = EgtGetInfo( vNullOutlines[i], WIN_SOU_OUTLINE, 'i') - if EgtGetName( EgtGetParent( EgtGetParent( abs( nSou)))) == WIN_VIRTUAL_AREA then - nSou = EgtGetInfo( abs( nSou), WIN_SOU_OUTLINE, 'i') - end - if EgtGetName( abs( nSou)) == WIN_SPLIT then - table.insert( vSplitIds, nSou) - tabSplitCrvName[abs( nSou)] = EgtGetName( vNullOutlines[i]) - end - end - elseif nParentType == WIN_AREATYPES.SPLIT and EgtGetInfo( nParentId, WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.FRENCH then - -- recupero l'indice dell'anta french dal suo nome - local sAreaName = EgtGetName( nAreaId) - local sAreaIdx = string.sub( sAreaName, string.len( WIN_AREA) + 1, string.len( WIN_AREA) + 1) - local nAreaIdx = tonumber( sAreaIdx) - local nSplitLayerId = EgtGetFirstNameInGroup( nParentId, WIN_SPLIT) - local vFrenchSplits = EgtGetAllInGroup( nSplitLayerId) - -- in base al numero di anta french recupero i french split che la definiscono con il corretto orientamento - if nAreaIdx > 1 then - table.insert( vSplitIds, - vFrenchSplits[nAreaIdx - 1]) - end - if nAreaIdx < #vFrenchSplits + 1 then - table.insert( vSplitIds, vFrenchSplits[nAreaIdx]) - end - end + if EgtGetInfo( nParentId, WIN_AREATYPE, 'i') == WIN_AREATYPES.FILL then + -- se inglesina il parent è un vetro. Il pezzo però non va tagliato con il vetro ma con l'elemento che contiene il vetro, quindi considero come outline quello del parent del vetro nParentId = EgtGetParent( nParentId) end - - if #vSplitIds == 0 then - -- salvo associazioni sou/child sugli outlines - for i = 1, #vCrvs do - local nSouOutlineId = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') - AddInfo( nSouOutlineId, WIN_CHILD_OUTLINE, vCrvs[i]) - end - else - - -- li ordino per id crescente in modo da effettuare i tagli nell'ordine corretto - table.sort( vSplitIds, function ( a, b) return abs( a) < abs( b) end) - - -- creo bordo complessivo dell'outline, salvando le info di SouOutline come temp prop della curva per non perderle - local vSouOutlines = {} - for i = 1, #vCrvs do - vSouOutlines[i] = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') - end - local nCompo = EgtCurveCompo( nOutlineLayerId, vCrvs) - for i = 0, #vCrvs - 1 do - EgtCurveCompoSetTempProp( nCompo, i, vSouOutlines[i+1]) - end - - -- taglio con split - for i = 1, #vSplitIds do - - -- a) creo la curva di outline corrispondente allo split - local nOutlineId = EgtCopy( abs( vSplitIds[i]), nOutlineLayerId) - -- rimuovo info che non voglio trasferire - EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE) - -- verifico orientamento - if vSplitIds[i] < 0 then - EgtInvertCurve( nOutlineId) - end - -- calcolo gli offset - local nProfileId = GetOutlineTheoricProfileId( abs( vSplitIds[i])) - if nProfileId then - local b3Profile = GetProfileLocalBox( nProfileId) - local sKey = EgtIf( tabSplitCrvName[abs( vSplitIds[i])] == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) - local dOverlap = EgtGetInfo( nProfileId, sKey, 'd') - local dRealDim = EgtGetInfo( abs( vSplitIds[i]), WIN_PART_DIM, 'd') - local dFillPerpOffset = abs( b3Profile:getMin():getX()) * dRealDim / b3Profile:getDimX() - dOverlap - EgtOffsetCurve( nOutlineId, - dFillPerpOffset) - else - -- è french split quindi non ha offset - end - - -- b) aggiorno la curva complessiva di outline con la curva appena calcolata - EgtExtendCurveStartByLen( nOutlineId, 1000) - EgtExtendCurveEndByLen( nOutlineId, 1000) - local ptS = EgtIP( nOutlineId, nCompo, EgtSP( nOutlineId)) - local ptE = EgtIP( nOutlineId, nCompo, EgtEP( nOutlineId)) - local dBorderParS = EgtCurveParamAtPoint( nCompo, ptS) - local dBorderParE = EgtCurveParamAtPoint( nCompo, ptE) - EgtTrimCurveStartEndAtParam( nCompo, dBorderParE, dBorderParS) - local dSplitParS = EgtCurveParamAtPoint( nOutlineId, ptS) - local dSplitParE = EgtCurveParamAtPoint( nOutlineId, ptE) - EgtTrimCurveStartEndAtParam( nOutlineId, dSplitParS, dSplitParE) - EgtAddCurveCompoCurve( nCompo, nOutlineId) - local _, dParEnd = EgtCurveDomain( nCompo) - EgtCurveCompoSetTempProp( nCompo, dParEnd - 1, vSplitIds[i]) - end - - -- spezzo la curva di outline nelle sue sottocurve e riassegno le info - local vTempProps = EgtCurveCompoGetTempProp( nCompo) - local nCrv, nCnt = EgtExplodeCurveCompo( nCompo) - for i = 0, nCnt - 1 do - local nOutlineId = nCrv + i - -- assegno le info sou/child - EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vTempProps[i+1]) - if vTempProps[i+1] > 0 then - AddInfo( vTempProps[i+1], WIN_CHILD_OUTLINE, nOutlineId) - else - AddInfo( abs( vTempProps[i+1]), WIN_CHILD_OUTLINE, - nOutlineId) - end - -- sistemo il nome - if EgtGetName( abs( vTempProps[i+1])) == WIN_SPLIT then - -- se deriva da split il nome è salvato nella tabella, se non lo fosse si tratta di un french split e lo calcolo al momento - local sName = tabSplitCrvName[abs( vTempProps[i+1])] - if sName then - EgtSetName( nOutlineId, sName) - else - AssignSplitName( nOutlineId) - end - else - EgtSetName( nOutlineId, EgtGetName( abs( vTempProps[i+1]))) - end - end - - -- riordino in modo da avere il bottom come prima curva - for i = 0, nCnt - 1 do - if EgtGetName( nCrv + i) ~= WIN_BOTTOM then - EgtRelocateGlob( nCrv + i, nOutlineLayerId, GDB_IN.LAST_SON) - else - break - end - end - end - - -- calcolo i profili - local vOutlineCrvs = EgtGetAllInGroup( nOutlineLayerId) - CalcSashProfiles( vOutlineCrvs, nAreaId) - - -- spostamento in z : recupero la quota da un profilo dell'anta - local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) - local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH) - local sSashProfile = EgtGetInfo( vOutlineCrvs[1], WIN_PROFILETYPE) - local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile) - local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd') - EgtMove( vOutlineCrvs, Z_AX() * dSashZOffset) - - return vOutlineCrvs -end - ---------------------------------------------------------------------- -local function VerifySashOutlines( vOutlines, nAreaId) - - -- controlla se i pezzi di un'anta sono validi e se necessitano di gestione speciale nel calcolo dei prev e dei next. Vi sono due tipologie di pezzi che richiedono gestione speciale : - -- a) extra : il pezzo non serve, il suo contributo si limita al trim dei suoi pezzi vicini con il suo bordo out - -- b) special : il pezzo è necessario ma non sufficiente per il trim dei suoi pezzi vicini, che vanno tagliati non solo con il pezzo stesso ma anche tra di loro - -- per distinguere i pezzi extra da special controllo se i semiprofili interni dei pezzi vicini si incontrano in un punto sensato per cui il pezzo risulta superfluo oppure no - - local nGrpTmp1 = EgtGroup( nAreaId) - local nGrpTmp2 = EgtGroup( nAreaId) - - -- recupero i bordi interni ed esterni dei semiprofili in - local vInSemiProfile = {} - local vOutSemiProfile = {} - for i = 1, #vOutlines do - - -- recupero il semiprofilo in - local nProfileId = GetOutlineTheoricProfileId( vOutlines[i]) - local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) - local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT) - local nInId = EgtGetFirstNameInGroup( nProfileId, WIN_IN) - local b3In = EgtGetBBoxRef( nInId, GDB_BB.STANDARD, frSectionFrame) - local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') - local dRealDim = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd') - - vInSemiProfile[i] = EgtCopyGlob( vOutlines[i], nGrpTmp1) - EgtSetInfo( vInSemiProfile[i], 'SouIdx', i) - -- se non è possibile calcolare l'interno ( e.g. arco con raggio inferiore alla sua dimensione) il pezzo è sicuramente extra ma considero comunque le sue curve nel fare i conti - -- per non sfalsare gli indici - if not EgtOffsetCurve( vInSemiProfile[i], b3In:getMin():getX() * dRealDim / dDimStd) then - EgtSetInfo( vOutlines[i], WIN_EXTRA_CRV, true) - end - - vOutSemiProfile[i] = EgtCopyGlob( vOutlines[i], nGrpTmp2) - EgtOffsetCurve( vOutSemiProfile[i], b3In:getMax():getX() * dRealDim / dDimStd) - EgtSetInfo( vOutSemiProfile[i], 'SouIdx', i) - end - - local _, vExtraIn = TrimOrderedCurves( vInSemiProfile, false) - -- se nessun bordo più interno scompare allora tutti i pezzi sono standard - if #vExtraIn == 0 then - EgtErase( nGrpTmp1) - EgtErase( nGrpTmp2) - return - end - - local _, vExtraOut = TrimOrderedCurves( vOutSemiProfile, false) - -- se il bordo esterno del suo profilo in scompare i suoi vicini si incontrano in modo sensato quindi il pezzo è sicuramente superfluo - for i = 1, #vExtraOut do - local nIdx = EgtGetInfo( vExtraOut[i], 'SouIdx', 'i') - EgtSetInfo( vOutlines[nIdx], WIN_EXTRA_CRV, true) - end - - -- analizzo i tratti con gestione speciale consecutivi insieme - local nOldId - local vExtraInGrps = {} - for i = 1, #vExtraIn do - local nIdx = EgtGetInfo( vExtraIn[i], 'SouIdx', 'i') - if not EgtGetInfo( vOutlines[nIdx], WIN_EXTRA_CRV, 'b') then - if not nOldId or EgtGetNext( nOldId) ~= vExtraIn[i] then - table.insert( vExtraInGrps, { vExtraIn[i]}) - else - table.insert( vExtraInGrps[#vExtraInGrps], vExtraIn[i]) - end - nOldId = vExtraIn[i] - end - end - - for i = 1, #vExtraInGrps do - - -- calcolo il punto di incontro dei semiprofili interni dei due pezzi vicini validi - local nIdx1 = EgtGetInfo( vExtraInGrps[i][1], 'SouIdx', 'i') - local nPrevIdx = EgtIf( nIdx1 == 1, #vOutlines, nIdx1-1) - while EgtGetInfo( vOutlines[nPrevIdx], WIN_EXTRA_CRV, 'b') do - nPrevIdx = EgtIf( nPrevIdx == 1, #vOutlines, nPrevIdx-1) - end - local nIdx2 = EgtGetInfo( vExtraInGrps[i][#vExtraInGrps[i]], 'SouIdx', 'i') - local nNextIdx = EgtIf( nIdx2 == #vOutlines, 1, nIdx2+1) - while EgtGetInfo( vOutlines[nNextIdx], WIN_EXTRA_CRV, 'b') do - nNextIdx = EgtIf( nNextIdx == #vOutlines, 1, nNextIdx+1) - end - local nPrevOut = vOutSemiProfile[nPrevIdx] - local nNextOut = vOutSemiProfile[nNextIdx] - local ptInters = FindIntersectionPoint( nPrevOut, nNextOut, EgtEP( nPrevOut)) - - -- ricavo le curva che delimita la regione valida per l'intersezione dei semiprofili dei pezzi vicini - local vCurrOutlines = {} - for j = 1, #vExtraInGrps[i] do - local nIdx = EgtGetInfo( vExtraInGrps[i][j], 'SouIdx', 'i') - vCurrOutlines[j] = vOutlines[nIdx] - end - local nCompoOutline = EgtCurveCompo( nGrpTmp1, vCurrOutlines, false) - local nProfileId = GetOutlineTheoricProfileId( vCurrOutlines[1]) - local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') - local dRealDim = EgtGetInfo( vCurrOutlines[1], WIN_PART_DIM, 'd') - local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) - local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT) - local nCPId = EgtGetFirstNameInGroup( nProfileId, WIN_OUT) - local b3CP = EgtGetBBoxRef( nCPId, GDB_BB.STANDARD, frSectionFrame) - local nRefCrv = EgtOffsetCurveAdv( nCompoOutline, b3CP:getMin():getX() * dRealDim / dDimStd) - local _, _, nSide = EgtPointCurveDistSide( ptInters, nRefCrv, Z_AX()) - - for j = 1, #vCurrOutlines do - -- se il punto di intersezione cade nella regione valida il pezzo è extra altrimenti è special - if nSide == -1 then - EgtSetInfo( vCurrOutlines[j], WIN_EXTRA_CRV, true) - else - EgtSetInfo( vCurrOutlines[j], WIN_SPECIAL_CRV, true) - end - end - end - - EgtErase( nGrpTmp1) - EgtErase( nGrpTmp2) -end - - ------------------------------- FILL ------------------------------- ---------------------------------------------------------------------- -local function CalculateFillOutline( nAreaId, nOutlineLayerId) - - -- recupero area parent di tipo telaio/anta che la contiene - local nParentArea = EgtGetParent( nAreaId) - local nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i') - while nAreaType ~= WIN_AREATYPES.FRAME and nAreaType ~= WIN_AREATYPES.SASH do - nParentArea = EgtGetParent( nParentArea) - nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i') - end - - -- 1) calcolo l'area complessiva di fill definita dal suo parent - local nParentOutlineLayer = EgtGetFirstNameInGroup( nParentArea, WIN_OUTLINE) - local dDeltaZ = 0 - local vParentOutlines = EgtGetAllInGroup( nParentOutlineLayer) - local vParentOffs = {} - -- calcolo gli offset + local nParentOutlineId = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE) + local vParentOutlines = EgtGetAllInGroup( nParentOutlineId) for i = 1, #vParentOutlines do - -- recupero il suo profilo per calcolare l'offset perpendicolare - local nParentProfileId = GetOutlineTheoricProfileId( vParentOutlines[i], true) - local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd') - if dOverlap then - local dRealDim = EgtGetInfo( vParentOutlines[i], WIN_PART_DIM, 'd') - -- verifico se contributo per bottomrail - local dRailOffs = 0 - if EgtGetName( nParentProfileId) == WIN_FILL_RAIL then - local nBottomRail = EgtGetInfo( vParentOutlines[i], WIN_BOTTOMRAIL, 'i') - dRailOffs = CalcRailOffset( vParentOutlines[i], nParentProfileId, nBottomRail) - local vBottomRailDims = EgtGetInfo( vParentOutlines[i], WIN_BOTTOMRAIL .. WIN_PART_DIM, 'vd') - dRealDim = vBottomRailDims[#vBottomRailDims] - end - local b3FrameProfile = GetProfileLocalBox( nParentProfileId) - local dDimRef = b3FrameProfile:getMin():getX() * dRealDim / b3FrameProfile:getDimX() - vParentOffs[i] = abs( dDimRef) - dOverlap + dRailOffs - -- movimento in z - if dDeltaZ < GEO.EPS_SMALL then - dDeltaZ = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd') - end - end - end - -- creo le curve di outlines - for i = 1, #vParentOutlines do - -- copio la curva di outline del parent - local nOutlineId = EgtCopy( vParentOutlines[i], nOutlineLayerId) + local nOutlineId = EgtCopyGlob( vParentOutlines[i], nOutlineLayerId) EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vParentOutlines[i]) - -- applico offset - if vParentOffs[i] then - EgtOffsetCurve( nOutlineId, - vParentOffs[i]) + AddInfo( vParentOutlines[i], WIN_CHILD_VIRTUAL_OUTLINE, nOutlineId) + end + + -- b) split + -- copio il layer di base split + local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) + local nSplitLayerId = EgtCopy( nBaseSplitLayerId, nAreaId) + EgtSetName( nSplitLayerId, WIN_SPLIT) + EgtSetStatus( nSplitLayerId, GDB_ST.OFF) + local vBaseSplitIds = EgtGetAllInGroup( nBaseSplitLayerId) + local vSplitIds = EgtGetAllInGroup( nSplitLayerId) + + -- aggiusto la quota degli split per allinearli all'outline + local dZMove = ( EgtSP( vParentOutlines[1]) - EgtSP( vSplitIds[1])) * Z_AX() + EgtMove( vSplitIds, dZMove * Z_AX()) + + -- aggiusto gli outlines e calcolo l'outline delle sottoaree null generate + local nSplitType = EgtGetInfo( vSplitIds[1], WIN_SPLITTYPE, 'i') + local bGrid = EgtGetInfo( nAreaId, WIN_GRID_SPLIT, 'b') or false + if bGrid then + AdjustGridSplitOutlines( nAreaId, vSplitIds) + else + AdjustSplitOutlines( nAreaId, vSplitIds, nOutlineLayerId, nSplitType) + end + + -- se inglesina su entrambi i lati creo copia degli outline per le inglesine esterne + if nSplitType == WIN_SPLITTYPES.MUNTIN_FILL then + local nMuntinType = EgtGetInfo( nAreaId, WIN_MUNTINFILL_SIDE, 'i') + if nMuntinType == WIN_MUNTINFILL_SIDES.BOTH then + local bSlide = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*'), WIN_SLIDE_WINDOW, 'b') or false + for i = 1, #vSplitIds do + local nId = EgtCopyGlob( vSplitIds[i], nSplitLayerId) + EgtSetInfo( vSplitIds[i], WIN_REF_MUNTIN, nId) + EgtSetInfo( vSplitIds[i], WIN_MUNTINFILL_SIDE, WIN_MUNTINFILL_SIDES.IN) + EgtSetInfo( nId, WIN_PROFILETYPE, EgtIf( bSlide, WIN_SLIDE .. '_', '') .. WIN_FILL_SPLIT_OUT) + EgtSetInfo( nId, WIN_MUNTINFILL_SIDE, WIN_MUNTINFILL_SIDES.OUT) + end else - -- se non ha offset definito è un pezzo che verrà tagliato da uno split ma, affinchè la forma del telaio sia coerente, devo applicare lo stesso offset a curve - -- che sono in tangenza - local nPrevIdx = EgtIf( i == 1, #vParentOutlines, i-1) - local nNextIdx = EgtIf( i == #vParentOutlines, 1, i+1) - if AreSameVectorApprox( EgtSV( vParentOutlines[i]), EgtEV( vParentOutlines[nPrevIdx])) then - while not vParentOffs[nPrevIdx] do - nPrevIdx = EgtIf( nPrevIdx == 1, #vParentOutlines, nPrevIdx-1) - end - EgtOffsetCurve( nOutlineId, - vParentOffs[nPrevIdx]) - vParentOffs[i] = vParentOffs[nPrevIdx] - elseif AreSameVectorApprox( EgtEV( vParentOutlines[i]), EgtSV( vParentOutlines[nNextIdx])) then - while not vParentOffs[nNextIdx] do - nNextIdx = EgtIf( nNextIdx == #vParentOutlines, 1, nNextIdx+1) - end - EgtOffsetCurve( nOutlineId, - vParentOffs[nNextIdx]) - vParentOffs[i] = vParentOffs[nNextIdx] + for i = 1, #vSplitIds do + EgtSetInfo( vSplitIds[i], WIN_MUNTINFILL_SIDE, nMuntinType) end end end - -- accorcio gli offset - local vCrvs = TrimOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) - -- applico spostamento verticale - EgtMove( vCrvs, Z_AX() * dDeltaZ) - - -- 2) taglio con split - local nParentType = EgtGetInfo( EgtGetParent( nAreaId), WIN_AREATYPE, 'i') - if nParentType ~= WIN_AREATYPES.NULL then - -- salvo associazioni sou/child - for i = 1, #vCrvs do - local nSouOutlineId = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') - AddInfo( nSouOutlineId, WIN_CHILD_OUTLINE, vCrvs[i]) - end - return - end - - -- creo bordo complessivo dell'outline, salvando le info come temp prop della curva per non perderle - local vSouOutlines = {} - for i = 1, #vCrvs do - vSouOutlines[i] = EgtGetInfo( vCrvs[i], WIN_SOU_OUTLINE, 'i') - end - local nCompo = EgtCurveCompo( nOutlineLayerId, vCrvs) - for i = 0, #vCrvs - 1 do - EgtCurveCompoSetTempProp( nCompo, i, vSouOutlines[i+1]) - end - - -- recupero gli split che definiscono l'area fill cercando gli split in tutte le aree parent di tipo null - local vSplitIds = {} - local nParentId = EgtGetParent( nAreaId) - while nParentId ~= nParentArea do - local nParentType = EgtGetInfo( nParentId, WIN_AREATYPE, 'i') - if nParentType == WIN_AREATYPES.NULL then - local nNullOutlineLay = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE) - local vNullOutlines = EgtGetAllInGroup( nNullOutlineLay) - for i = 1, #vNullOutlines do - local nSou = EgtGetInfo( vNullOutlines[i], WIN_SOU_OUTLINE, 'i') - if EgtGetName( EgtGetParent( EgtGetParent( abs( nSou)))) == WIN_VIRTUAL_AREA then - nSou = EgtGetInfo( abs( nSou), WIN_SOU_OUTLINE, 'i') - end - if EgtGetName( abs( nSou)) == WIN_SPLIT then - table.insert( vSplitIds, nSou) - end - end - end - nParentId = EgtGetParent( nParentId) - end - - -- li ordino per id crescente in modo da effettuare i tagli nell'ordine corretto - table.sort( vSplitIds, function ( a, b) return abs( a) < abs( b) end) - - for i = 1, #vSplitIds do - - -- creo la curva di outline corrispondente allo split - local nOutlineId = EgtCopy( abs( vSplitIds[i]), nOutlineLayerId) - if vSplitIds[i] < 0 then - EgtInvertCurve( nOutlineId) - end - -- calcolo gli offset - local nProfileId = GetOutlineTheoricProfileId( abs( vSplitIds[i]), true) - local b3Profile = GetProfileLocalBox( nProfileId) - local dOverlap = EgtGetInfo( nProfileId, WIN_FILLOVERLAP, 'd') - local dDimRef = EgtIf( vSplitIds[i] < 0, b3Profile:getMax():getX(), b3Profile:getMin():getX()) - local dRealDim = EgtGetInfo( abs( vSplitIds[i]), WIN_PART_DIM, 'd') - local dOffs = abs( dDimRef) * dRealDim / b3Profile:getDimX() - dOverlap - EgtOffsetCurve( nOutlineId, - dOffs) - -- movimento in z - local dFillZOffset = EgtGetInfo( nProfileId, WIN_FILLDELTA, 'd') - EgtMove( nOutlineId, Z_AX() * dFillZOffset) - - -- aggiorno la curva complessiva di outline con la curva appena calcolata - local ptS = EgtIP( nOutlineId, nCompo, EgtSP( nOutlineId)) - local ptE = EgtIP( nOutlineId, nCompo, EgtEP( nOutlineId)) - local dBorderParS = EgtCurveParamAtPoint( nCompo, ptS) - local dBorderParE = EgtCurveParamAtPoint( nCompo, ptE) - EgtTrimCurveStartEndAtParam( nCompo, dBorderParE, dBorderParS) - local dSplitParS = EgtCurveParamAtPoint( nOutlineId, ptS) - local dSplitParE = EgtCurveParamAtPoint( nOutlineId, ptE) - EgtTrimCurveStartEndAtParam( nOutlineId, dSplitParS, dSplitParE) - EgtAddCurveCompoCurve( nCompo, nOutlineId) - local _, dParEnd = EgtCurveDomain( nCompo) - EgtCurveCompoSetTempProp( nCompo, dParEnd - 1, vSplitIds[i]) - end - - -- spezzo la curva di outline nelle sue sottocurve e riassegno le info - local vTempProps = EgtCurveCompoGetTempProp( nCompo) - local nCrv, nCnt = EgtExplodeCurveCompo( nCompo) - for i = 0, nCnt - 1 do - EgtSetInfo( nCrv + i, WIN_SOU_OUTLINE, vTempProps[i+1]) - if vTempProps[i+1] > 0 then - AddInfo( vTempProps[i+1], WIN_CHILD_OUTLINE, nCrv + i) - else - AddInfo( abs( vTempProps[i+1]), WIN_CHILD_OUTLINE, - ( nCrv + i)) - end - end end -------------------- AGGIORNAMENTO TIPOLOGIE ---------------------- --------------------------------------------------------------------- --- funzione ricorsiva che aggiorna le tipologie di split guardando le curve di outlines ( e non quelle di base outlines come fatto in CalcProfileType) -local function UpdateSplitTypes( nAreaId) - - local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') +local function CreateSplitTestBox( nOutlineId, nProfileId, b3Profile, bStart) - if nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then - return + local frBox + local b3Box + + local dDimStd = b3Profile:getDimX() + local dDimReal = EgtGetInfo( nOutlineId, WIN_PART_DIM, 'd') + + local dFillOverlap = EgtGetInfo( nProfileId, WIN_FIXED_REF, 'd') + local dSashOverlap = EgtGetInfo( nProfileId, WIN_SASH_REF .. '1', 'd') + local nChild1 = EgtGetInfo( nOutlineId, EgtIf( bStart, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '1', 'i') + + local dOffsMax = b3Profile:getMax():getX() * dDimReal / dDimStd - EgtIf( nChild1 == WIN_CHILDREN_TYPES.SASH, dSashOverlap, dFillOverlap) + local dOffsMin = b3Profile:getMin():getX() * dDimReal / dDimStd + EgtIf( nChild1 == WIN_CHILDREN_TYPES.SASH, dFillOverlap, dSashOverlap) - elseif nAreaType == WIN_AREATYPES.SPLIT then - if EgtGetInfo( nAreaId, WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.FRENCH then - local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) - local vSplits = EgtGetAllInGroup( nSplitLayerId) - for i = 1, #vSplits do - - -- identifico la tipologia di figli dal lato destro (1) e sinistro (2) - local tabChildren = {{}, {}} - local vSashNbr = { 0, 0} - local vFillNbr = { 0, 0} - local vBaseChildren = EgtGetInfo( vSplits[i], WIN_CHILD_VIRTUAL_OUTLINE, 'vi') - -- ordino i figli letti dalle info in modo tale che quello di destra ( che ha segno negativo) sia il primo e quello di sinistra ( che ha segno positivo) sia il secondo - if vBaseChildren[1] > vBaseChildren[2] then - vBaseChildren[1], vBaseChildren[2] = vBaseChildren[2], vBaseChildren[1] - end - - for k = 1, 2 do - local vCurrChildren = { vBaseChildren[k]} - local j = 1 - while vCurrChildren[j] do - local vNewChildren = EgtGetInfo( abs( vCurrChildren[j]), WIN_CHILD_VIRTUAL_OUTLINE, 'vi') - if vNewChildren then - EgtJoinTables( vCurrChildren, vNewChildren) - else - -- se non ha ulteriori figli allora è l'area null finale che deve essere studiata - local nNullAreaId = EgtGetParent( EgtGetParent( abs( vCurrChildren[j]))) - local nAreaId = EgtGetFirstNameInGroup( nNullAreaId, WIN_AREA .. '*') - local nAreaType - if nAreaId then - nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') - if nAreaType == WIN_AREATYPES.SASH then - vSashNbr[k] = vSashNbr[k] + 1 - elseif nAreaType == WIN_AREATYPES.FILL then - vFillNbr[k] = vFillNbr[k] + 1 - end - end - table.insert( tabChildren[k], { nId = abs( vCurrChildren[j]), nType = nAreaType}) - end - j = j + 1 - end - end - - -- ricavo la nuova tipologia di split ed eventualmente aggiorno il profilo se fosse diverso da quello calcolato dai base outlines - local nOldType = EgtGetInfo( vSplits[i], WIN_SPLITTYPE, 'i') - - -- se figli sono solo ante è montante - if vFillNbr[1] == 0 and vFillNbr[2] == 0 then - if nOldType ~= WIN_SPLITTYPES.MULLION then - EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MULLION) - if AreSameOrOppositeVectorApprox( EgtSV( vSplits[i]), X_AX()) then - EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_SASH_HORIZONTAL) - else - EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_SASH_VERTICAL) - end - end - - -- se figli sono solo vetri fissi è muntin interno al telaio - elseif vSashNbr[1] == 0 and vSashNbr[2] == 0 then - if nOldType ~= WIN_SPLITTYPES.MUNTIN_FRAME then - EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MUNTIN_FRAME) - EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_FRAME_SPLIT) - end - - -- se figli di entrambe le tipologie è mixed e verifico quali sono le parti dello split coinvolte dal cambio profilo - else - local nPrfChange = 0 - -- ricavo le tipologie di figli su start ed end a destra - local nStart1, nEnd1 - if vSashNbr[1] > 0 and vFillNbr[1] == 0 then - nStart1 = WIN_CHILDREN_TYPES.SASH - nEnd1 = WIN_CHILDREN_TYPES.SASH - elseif vSashNbr[1] == 0 and vFillNbr[1] > 0 then - nStart1 = WIN_CHILDREN_TYPES.FILL - nEnd1 = WIN_CHILDREN_TYPES.FILL - else - nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.OUT -- ha cambio profilo sul lato esterno - for j = 1, #tabChildren[1] do - if AreSamePointApprox( EgtSP( vSplits[i]), EgtEP( tabChildren[1][j].nId)) then - nStart1 = EgtIf( tabChildren[1][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL) - end - if AreSamePointApprox( EgtEP( vSplits[i]), EgtSP( tabChildren[1][j].nId)) then - nEnd1 = EgtIf( tabChildren[1][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL) - end - end - end - - -- ricavo le tipologie di figli su start ed end a sinistra - local nStart2, nEnd2 - if vSashNbr[2] > 0 and vFillNbr[2] == 0 then - nStart2 = WIN_CHILDREN_TYPES.SASH - nEnd2 = WIN_CHILDREN_TYPES.SASH - elseif vSashNbr[2] == 0 and vFillNbr[2] > 0 then - nStart2 = WIN_CHILDREN_TYPES.FILL - nEnd2 = WIN_CHILDREN_TYPES.FILL - else - nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.IN -- ha cambio profilo su lato interno - for j = 1, #tabChildren[2] do - if AreSamePointApprox( EgtSP( vSplits[i]), EgtSP( tabChildren[2][j].nId)) then - nStart2 = EgtIf( tabChildren[2][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL) - end - if AreSamePointApprox( EgtEP( vSplits[i]), EgtEP( tabChildren[2][j].nId)) then - nEnd2 = EgtIf( tabChildren[2][j].nType == WIN_AREATYPES.SASH, WIN_CHILDREN_TYPES.SASH, WIN_CHILDREN_TYPES.FILL) - end - end - end - - -- se le tipologie di figli sugli estremi sono diverse tra destra e sinistra allora l'estremo è coinvolto dal cambio profilo - if nStart1 ~= nStart2 then - nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.START - end - if nEnd1 ~= nEnd2 then - nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.END - end - - EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MIXED) - EgtSetInfo( vSplits[i], WIN_PRF_CHANGE, nPrfChange) - EgtSetInfo( vSplits[i], WIN_MIXED_START_CHILDREN .. '1', nStart1) - EgtSetInfo( vSplits[i], WIN_MIXED_START_CHILDREN .. '2', nStart2) - EgtSetInfo( vSplits[i], WIN_MIXED_END_CHILDREN .. '1', nEnd1) - EgtSetInfo( vSplits[i], WIN_MIXED_END_CHILDREN .. '2', nEnd2) - end - end - end + if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE then + -- oriento il box come la curva + frBox = Frame3d( EgtSP( nOutlineId), Z_AX(), EgtSV( nOutlineId)) + b3Box = EgtGetBBoxRef( nOutlineId, GDB_BB.STANDARD, frBox) + + -- ingrandisco il box con punti opportuni per tenere conto delle dimensioni del pezzo + local vtDir = VectorFromRotated( EgtSV( nOutlineId), Z_AX(), -90) + local ptMin = EgtSP( nOutlineId) + vtDir * dOffsMax + local ptMax = EgtSP( nOutlineId) + vtDir * dOffsMin + + ptMin:toLoc( frBox) + ptMax:toLoc( frBox) + + b3Box:Add( ptMin) + b3Box:Add( ptMax) + + else + -- calcolo il rettangolo di area minima che racchiude il pezzo + local nOffsMax = EgtOffsetCurveAdv( nOutlineId, dOffsMax) + local nOffsMin = EgtOffsetCurveAdv( nOutlineId, dOffsMin) + EgtInvertCurve( nOffsMin) + local nCompo = EgtCurveCompo( EgtGetParent( nOutlineId), nOffsMax) + EgtAddCurveCompoLine( nCompo, EgtSP( nOffsMin)) + EgtAddCurveCompoCurve( nCompo, nOffsMin) + EgtCloseCurveCompo( nCompo) + frBox = EgtCurveMinAreaRectangleXY( nCompo) + b3Box = EgtGetBBoxRef( nCompo, GDB_BB.STANDARD, frBox) + EgtErase( nCompo) end - -- analizzo le sottoaree - local vChildren = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') - for i = 1, #vChildren do - UpdateSplitTypes( vChildren[i]) + return b3Box, frBox +end + + --------------------------------------------------------------------- +local function TrimTestSurf( nCrvId, nCrvTrimId, nTrimProfileId, bTrimWithPrev, nSurfId, nGrpTmp) + + local nPrevId = EgtIf( bTrimWithPrev, nCrvTrimId, nCrvId) + local nNextId = EgtIf( bTrimWithPrev, nCrvId, nCrvTrimId) + + -- se sono entrambi pezzi di telaio taglio con bisettrice ( perchè la giunzione sarà forzata ad angled) + if EgtGetName( nCrvId) ~= WIN_SPLIT and EgtGetName( nCrvTrimId) ~= WIN_SPLIT then + if EgtGetType( nCrvId) == GDB_TY.CRV_LINE and EgtGetType( nCrvTrimId) == GDB_TY.CRV_LINE then + local vtN = 0.5 * ( EgtSV( nNextId) - EgtEV( nPrevId)) + if vtN:isZero() then + vtN = - EgtSV( nNextId) + else + vtN:rotate( Z_AX(), EgtIf( bTrimWithPrev, 90, -90)) + end + EgtCutSurfTmPlane( nSurfId, EgtSP( nNextId), vtN, false) + + else + -- calcolo bisettore + local nBisector = CalcParabolicBisector( nPrevId, nNextId, 100, nGrpTmp, false, false) + EgtMove( nBisector, 2 * Z_AX()) + local nBisectorSurf = EgtSurfTmByRegionExtrusion( nGrpTmp, nBisector, - 100 * Z_AX()) + EgtSurfTmCut( nSurfId, nBisectorSurf, bTrimWithPrev, false) + end + + -- se è pezzo di telaio e di split taglio con il controprofilo + else + local nGuideId = EgtCopyGlob( abs( nCrvTrimId), nGrpTmp) + local dDimStd = EgtGetInfo( nTrimProfileId, WIN_DIM_STD, 'd') + local dDimReal = EgtGetInfo( abs( nCrvTrimId), WIN_PART_DIM, 'd') + if abs( dDimReal - dDimStd) > GEO.EPS_SMALL then + local dOffs = dDimReal / dDimStd + EgtOffsetCurve( nGuideId, - dOffs) + end + local sSemiProfile = WIN_SASH .. WIN_CTRIN + if EgtGetName( abs( nCrvTrimId)) == WIN_SPLIT then + if nCrvTrimId < 0 then + sSemiProfile = sSemiProfile .. '1' + else + sSemiProfile = sSemiProfile .. '2' + end + end + local nTrimSurf = CreateProfileSurf( nGuideId, nTrimProfileId, WIN_OFST .. sSemiProfile, 100, nGrpTmp) + EgtSurfTmCut( nSurfId, nTrimSurf, true, false) end end --------------------------------------------------------------------- -local function VerifyOutlinesInterferenceWithMixedSplit( nAreaId, vOutlines) - +local function TestMixedInterference( nSplitId, bStart, tabMixedProfiles, tabBox, nGrpTmp) + local vInterference = {} - local vToBeTested = {} - for i = 1, #vOutlines do - vInterference[i] = false - vToBeTested[i] = false + + -- creo il box di riferimento dello split + local nRefCrv = EgtCopyGlob( nSplitId, nGrpTmp) + if bStart then + EgtTrimCurveEndAtLen( nRefCrv, 0.5 * EgtCurveLength( nRefCrv)) + else + EgtTrimCurveStartAtLen( nRefCrv, 0.5 * EgtCurveLength( nRefCrv)) + end + local b3Box, frRef = CreateSplitTestBox( nRefCrv, tabMixedProfiles[3].nId, tabMixedProfiles[3].b3Box, bStart) + + -- ricavo gli indici degli outlines con i quali fa interferenza + local vTest = {} + for k = 1, #tabBox do + if Overlaps( tabBox[k].b3Box, tabBox[k].frRef, b3Box, frRef) then + table.insert( vTest, k) + end end - local nGrpTmp = EgtGroup( nAreaId) + if #vTest == 1 then + vInterference = { tabBox[vTest[1]].nId} + + else + -- costruisco il solido di split approssimato come parallelepipedo + b3Box:expand( 0, 0, 0.5 * tabMixedProfiles[3].b3Box:getDimY() + 1) + local nSplitSolid = EgtSurfTmBBox( nGrpTmp, b3Box) + EgtMove( nSplitSolid, - 0.5 * tabMixedProfiles[3].b3Box:getDimY() * Z_AX()) + EgtTransform( nSplitSolid, frRef) + + for j = 1, #vTest do + + -- creo la superficie di test + local nIdx = vTest[j] + local nGuideId = EgtCopyGlob( abs( tabBox[nIdx].nId), nGrpTmp) + local dDimStd = EgtGetInfo( tabBox[nIdx].nProfileId, WIN_DIM_STD, 'd') + local dDimReal = EgtGetInfo( abs( tabBox[nIdx].nId), WIN_PART_DIM, 'd') + if abs( dDimReal - dDimStd) > GEO.EPS_SMALL then + local dOffs = dDimReal / dDimStd + EgtOffsetCurve( nGuideId, - dOffs) + end + local sSemiProfile = WIN_SASH .. WIN_CTRIN + if EgtGetName( abs( tabBox[nIdx].nId)) == WIN_SPLIT then + if tabBox[nIdx].nId < 0 then + sSemiProfile = sSemiProfile .. '1' + else + sSemiProfile = sSemiProfile .. '2' + end + end + local nSurf = CreateProfileSurf( nGuideId, tabBox[nIdx].nProfileId, sSemiProfile, 100, nGrpTmp) + + -- la taglio con eventuali vicine + if j > 1 and vTest[j] == vTest[j-1] + 1 then + local nIdxPrev = vTest[j-1] + TrimTestSurf( abs( tabBox[nIdx].nId), abs( tabBox[nIdxPrev].nId), tabBox[nIdxPrev].nProfileId, true, nSurf, nGrpTmp) + end + if j < #vTest and vTest[j] == vTest[j+1] - 1 then + local nIdxNext = vTest[j+1] + TrimTestSurf( abs( tabBox[nIdx].nId), abs( tabBox[nIdxNext].nId), tabBox[nIdxNext].nProfileId, false, nSurf, nGrpTmp) + end + + -- verifico se interferenza + local nId, _, nCrvCnt = EgtSurfTmSurfTmInters( nSplitSolid, nSurf, nGrpTmp) + if nId and nCrvCnt > 0 then + table.insert( vInterference, tabBox[nIdx].nId) + end + end + + -- TODO è possibile che cambio profilo coinvolga pezzo del telaio e di split contemporaneamente? Oppure va segnalato errore? + end + + return vInterference +end + +--------------------------------------------------------------------- +-- funzione che verifica per gli split che hanno cambio profilo sull'estremo quali pezzi del telaio/split saranno influenzati dal cambio profilo +local function VerifyProfileChangeSplitInterference( nSplitId, tabMixedProfiles, bStart, bEnd) + + local nGrpTmp = EgtGroup( GDB_ID.ROOT) EgtSetStatus( nGrpTmp, GDB_ST.OFF) + + -- recupero outline con cui viene tagliato + local nStartIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'i') + local nOutlineLayerId = EgtGetParent( nStartIntersId) + local vOutlines = EgtGetAllInGroup( nOutlineLayerId) + + -- calcolo i box delle curve di outlines + local tabBox = {} + for i = 1, #vOutlines do + local nSou = GetNonVirtualOutline( vOutlines[i]) + -- recupero il profilo teorico e il suo box dalla tabella dei profili + local nMixedProfileIdx = 1 + if EgtGetName( abs( nSou)) == WIN_BOTTOM then + nMixedProfileIdx = 2 + elseif EgtGetName( abs( nSou)) == WIN_SPLIT then + nMixedProfileIdx = 3 + end + local nProfileId = tabMixedProfiles[nMixedProfileIdx].nId + local b3Profile = tabMixedProfiles[nMixedProfileIdx].b3Box + + -- calcolo il box ottimale della curva di outline + local b3Box, frRef = CreateTestBoxFromOutline( abs( nSou), nProfileId, b3Profile) + tabBox[i] = { frRef = frRef, b3Box = b3Box, nId = nSou, nProfileId = nProfileId} + end + + if bStart then + local vInterf = TestMixedInterference( nSplitId, true, tabMixedProfiles, tabBox, nGrpTmp) + -- assegno le info + EgtSetInfo( nSplitId, WIN_MIXED_PREV, vInterf) + for j = 1, #vInterf do + if vInterf[j] < 0 then + AddInfo( abs( vInterf[j]), WIN_CHILD_PRFCHANGE_SPLIT, - nSplitId) + else + AddInfo( vInterf[j], WIN_CHILD_PRFCHANGE_SPLIT, nSplitId) + end + end + end + + if bEnd then + local vInterf = TestMixedInterference( nSplitId, false, tabMixedProfiles, tabBox, nGrpTmp) + -- assegno info + EgtSetInfo( nSplitId, WIN_MIXED_NEXT, vInterf) + for j = 1, #vInterf do + if vInterf[j] < 0 then + AddInfo( abs( vInterf[j]), WIN_CHILD_PRFCHANGE_SPLIT, - nSplitId) + else + AddInfo( vInterf[j], WIN_CHILD_PRFCHANGE_SPLIT, nSplitId) + end + end + end + + EgtErase( nGrpTmp) +end + +--------------------------------------------------------------------- +-- funzione ricorsiva che aggiorna le tipologie e i profili di split guardando le curve di outlines ( e non quelle di base outlines come fatto in CalcProfileType) +local function UpdateSplitTypes( nAreaId) + + -- lo split può avere cambio profilo : + -- a) sull'estremo : se i figli dal lato destro e sinistro su tale estremo sono di tipologie diverse + -- b) sul lato : se e solo se su di esso giace l'estremo di uno split che ha cambio profilo proprio su quell'estremo -- ricavo i profili mixed teorici local nProfileGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) @@ -2830,192 +3024,179 @@ local function VerifyOutlinesInterferenceWithMixedSplit( nAreaId, vOutlines) local b3Top = GetProfileLocalBox( nTopProfileId) local nSplitProfileId = EgtGetFirstNameInGroup( nFrameProfileGrp, WIN_MIXED_SPLIT) local b3Split = GetProfileLocalBox( nSplitProfileId) + local tMixedProfiles = { { nId = nTopProfileId, b3Box = b3Top}, { nId = nBottomProfileId, b3Box = b3Bottom}, { nId = nSplitProfileId, b3Box = b3Split}} - -- calcolo i box delle curve di outlines - local tabBox = {} - for i = 1, #vOutlines do - local nProfileId = EgtIf( i == 1, nBottomProfileId, nTopProfileId) - local b3Profile = EgtIf( i == 1, b3Bottom, b3Top) - local b3Box, frRef = CreateTestBoxFromOutline( vOutlines[i], nProfileId, b3Profile) - tabBox[i] = { frRef = frRef, b3Box = b3Box} - end - - - -- recupero tutti gli split con cambio profilo sugli estremi che arrivano sul telaio - local tabSplits = {} - local vChildAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') + -- recupero tutti gli split derivanti direttamente dell'area frame + local vStack = { nAreaId} + local vSplits = {} local i = 1 - while vChildAreas[i] do - local nAreaType = EgtGetInfo( vChildAreas[i], WIN_AREATYPE, 'i') - if nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then - -- la ricerca a cascata si interrompe - else - if nAreaType == WIN_AREATYPES.SPLIT then - local nSplitLayerId = EgtGetFirstNameInGroup( vChildAreas[i], WIN_SPLIT) - local vSplits = EgtGetAllInGroup( nSplitLayerId) - for j = 1, #vSplits do - - local nPrfChange = EgtGetInfo( vSplits[j], WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL - if nPrfChange & WIN_PRF_CHANGE_TYPES.START > 0 then - local nBaseStart = EgtGetInfo( vSplits[j], WIN_SPLIT_STARTINTERS, 'i') - local nStart = GetNonVirtualOutline( nBaseStart) - if EgtGetName( abs( nStart)) ~= WIN_SPLIT then - -- controllo con quanti outlines fa interferenza controllando l'overlap dei box - local nRefCrv = EgtCopyGlob( vSplits[j], nGrpTmp) - EgtTrimCurveEndAtLen( nRefCrv, 0.5 * EgtCurveLength( nRefCrv)) - local b3Box, frRef = CreateTestBoxFromOutline( nRefCrv, nSplitProfileId, b3Split) - - local vTest = {} -- indici degli outlines con cui fa interferenza - for k = 1, #tabBox do - if Overlaps( tabBox[k].b3Box, tabBox[k].frRef, b3Box, frRef) then - table.insert( vTest, k) - end - end - - if #vTest == 1 then - -- se fa intereferenza con una sola curva non servono ulteriori controlli, l'interferenza è confermata - vInterference[vTest[1]] = true - AddInfo( vOutlines[vTest[1]], WIN_CHILD_PRFCHANGE_SPLIT, vSplits[j]) - EgtSetInfo( vSplits[j], WIN_PREV_OUTLINES, vOutlines[vTest[1]]) - EgtSetInfo( vSplits[j], WIN_STARTJOINT, WIN_PART_JNT.SHORT) - elseif #vTest > 1 then - -- se fa interferenza con più curve allora dovrò controllare quali sono le vere interferenze controllando i profili - table.insert( tabSplits, { nId = vSplits[j], bStart = true, vTest = vTest}) - for k = 1, #vTest do - vToBeTested[vTest[k]] = true - end - end - end - end - - if nPrfChange & WIN_PRF_CHANGE_TYPES.END > 0 then - local nBaseEnd = EgtGetInfo( vSplits[j], WIN_SPLIT_ENDINTERS, 'i') - local nEnd = GetNonVirtualOutline( nBaseEnd) - if EgtGetName( abs( nEnd)) ~= WIN_SPLIT then - local nRefCrv = EgtCopyGlob( vSplits[j], nGrpTmp) - EgtTrimCurveStartAtLen( nRefCrv, 0.5 * EgtCurveLength( nRefCrv)) - local b3Box, frRef = CreateTestBoxFromOutline( nRefCrv, nSplitProfileId, b3Split) - - local vTest = {} - for k = 1, #tabBox do - if Overlaps( tabBox[k].b3Box, tabBox[k].frRef, b3Box, frRef) then - table.insert( vTest, k) - end - end - - if #vTest == 1 then - vInterference[vTest[1]] = true - AddInfo( vOutlines[vTest[1]], WIN_CHILD_PRFCHANGE_SPLIT, vSplits[j]) - EgtSetInfo( vSplits[j], WIN_NEXT_OUTLINES, vOutlines[vTest[1]]) - EgtSetInfo( vSplits[j], WIN_ENDJOINT, WIN_PART_JNT.SHORT) - elseif #vTest > 1 then - table.insert( tabSplits, { nId = vSplits[j], bStart = false, vTest = vTest}) - for k = 1, #vTest do - vToBeTested[vTest[k]] = true - end - end - end - end - end + while vStack[i] do + local nAreaType = EgtGetInfo( vStack[i], WIN_AREATYPE, 'i') + if nAreaType == WIN_AREATYPES.SPLIT then + if EgtGetInfo( vStack[i], WIN_SPLITTYPE, 'i') ~= WIN_SPLITTYPES.FRENCH then + local nSplitLayerId = EgtGetFirstNameInGroup( vStack[i], WIN_SPLIT) + local vCurrSplits = EgtGetAllInGroup( nSplitLayerId) + EgtJoinTables( vSplits, vCurrSplits) end - -- analizzo le sottaree - local vCurrChildAreas = EgtGetNameInGroup( vChildAreas[i], WIN_AREA .. '*') - EgtJoinTables( vChildAreas, vCurrChildAreas) + end + -- se non si è arrivati ad area sash o fill salvo i figli per cercare ulteriori split + if nAreaType ~= WIN_AREATYPES.SASH and nAreaType ~= WIN_AREATYPES.FILL then + local vChildren = EgtGetNameInGroup( vStack[i], WIN_AREA .. '*') + EgtJoinTables( vStack, vChildren) end i = i + 1 end - -- per ogni curva di outline che deve essere testata costruisco la superficie in con il controprofilo sash ( perchè è quella che verrà usata per tagliare lo split) - local vTestSurfs = {} - for i = 1, #vOutlines do - if vToBeTested[i] then - local nProfileId = EgtIf( i == 1, nBottomProfileId, nTopProfileId) - local nGuideId = EgtCopyGlob( vOutlines[i], nGrpTmp) - local dDimStd = EgtGetInfo( nProfileId, WIN_DIM_STD, 'd') - local dDimReal = EgtGetInfo( vOutlines[i], WIN_PART_DIM, 'd') - if abs( dDimReal - dDimStd) > GEO.EPS_SMALL then - local dOffs = dDimReal / dDimStd - EgtOffsetCurve( nGuideId, - dOffs) - end - vTestSurfs[i] = CreateProfileSurf( nGuideId, nProfileId, WIN_SASH .. WIN_CTRIN, 100, nGrpTmp) - end - end - - -- taglio le superfici con bisettrice ( perchè se entrambi i pezzi hanno cambio profilo la giunzione viene forzata a angled) - for i = 1, #vOutlines do - local nPrevIdx = EgtIf( i == 1, #vOutlines, i - 1) - if vTestSurfs[i] or vTestSurfs[nPrevIdx] then - if EgtGetType( vOutlines[i]) == GDB_TY.CRV_LINE and EgtGetType( vOutlines[nPrevIdx]) == GDB_TY.CRV_LINE then - local vtDir = 0.5 * ( EgtSV( vOutlines[i]) - EgtEV( vOutlines[nPrevIdx])) - if vtDir:isZero() then - vtDir = - EgtSV( vOutlines[i]) - else - vtDir:rotate( Z_AX(), 90) - end - if vTestSurfs[i] then - EgtCutSurfTmPlane( vTestSurfs[i], EgtSP( vOutlines[i]), vtDir, false) - end - if vTestSurfs[nPrevIdx] then - EgtCutSurfTmPlane( vTestSurfs[nPrevIdx], EgtSP( vOutlines[i]), - vtDir, false) - end - else - -- calcolo bisettore - local nBisector = CalcParabolicBisector( vOutlines[nPrevIdx], vOutlines[i], 100, nGrpTmp, false, false) - local nBisectorSurf = EgtSurfTmByRegionExtrusion( nGrpTmp, nBisector, - 100 * Z_AX()) - if vTestSurfs[i] then - EgtSurfTmCut( vTestSurfs[i], nBisectorSurf, true, false) - end - if vTestSurfs[nPrevIdx] then - EgtSurfTmCut( vTestSurfs[nPrevIdx], nBisectorSurf, false, false) - end - end - end - end - - -- verifico le intereferernze - for i = 1, #tabSplits do + -- analizzo gli split partendo dagli ultimi + for i = #vSplits, 1, -1 do - -- costruisco il profilo dello split sull'estremo considerato in base alla tipologia di figli - local nChildrenType1 = EgtGetInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '1', 'i') - local sSemiProfileName1 = EgtIf( nChildrenType1 == WIN_CHILDREN_TYPES.SASH, WIN_SASH, WIN_FILL) .. WIN_IN .. '1' - local nSemiProfile1 = EgtGetFirstNameInGroup( nSplitProfileId, sSemiProfileName1) - - local nChildrenType2 = EgtGetInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '2', 'i') - local sSemiProfileName2 = EgtIf( nChildrenType2 == WIN_CHILDREN_TYPES.SASH, WIN_SASH, WIN_FILL) .. WIN_IN .. '2' - local nSemiProfile2 = EgtGetFirstNameInGroup( nSplitProfileId, sSemiProfileName2) - - local dDimStd = EgtGetInfo( nSplitProfileId, WIN_DIM_STD, 'd') - local dDimReal = EgtGetInfo( tabSplits[i].nId, WIN_PART_DIM, 'd') - if abs( dDimReal - dDimStd) > GEO.EPS_SMALL then - local nSectionFrame = EgtGetFirstNameInGroup( nSplitProfileId, WIN_SECTIONFRAME) - local frProfile = EgtFR( nSectionFrame, GDB_ID.ROOT) - EgtMove( nSemiProfile1, b3Split:getMax():getX() * dDimReal / dDimStd * frProfile:getVersX(), GDB_RT.GLOB) - EgtMove( nSemiProfile1, b3Split:getMin():getX() * dDimReal / dDimStd * frProfile:getVersX(), GDB_RT.GLOB) + -- verifico se sullo split corrente arrivano gli estremi di split che hanno cambio profilo sull'estremo in questione. Tali split sono salvati nella info WIN_CHILD_PRFCHANGE_SPLIT, + -- quindi verifico se ci sono e li classifico in base al lato su cui arrivano ( dx (1) o sx (2)) + local vSplitChildren = EgtGetInfo( vSplits[i], WIN_CHILD_PRFCHANGE_SPLIT, 'vi') or {} + local vForcedCP = { {}, {}} + for k = 1, #vSplitChildren do + if vSplitChildren[k] < 0 then + table.insert( vForcedCP[1], abs( vSplitChildren[k])) + else + table.insert( vForcedCP[2], vSplitChildren[k]) + end end - local nSection = EgtCurveCompo( nGrpTmp, nSemiProfile1, false) - EgtAddCurveCompoLine( nSection, EgtSP( nSemiProfile2, GDB_ID.ROOT), GDB_RT.GLOB) - EgtAddCurveCompoCurve( nSection, nSemiProfile2, false) - EgtCloseCurveCompo( nSection) + + -- recupero i figli e li ordino in modo tale che quello di destra ( che ha segno negativo) sia il primo e quello di sinistra ( che ha segno positivo) sia il secondo + local vBaseChildren = EgtGetInfo( vSplits[i], WIN_CHILD_VIRTUAL_OUTLINE, 'vi') + vBaseChildren[1], vBaseChildren[2] = vBaseChildren[2], vBaseChildren[1] + + -- analizzo i lati dello split per vedere se hanno cambio profilo e per recuperare la tipologia di figli sugli estremi + local nPrfChange = 0 + local vStart = { 0, 0} + local vEnd = { 0, 0} + + for k = 1, 2 do - -- costruisco il solido di split - local nSplitSolid = CreateProfileSurfById( tabSplits[i].nId, nSplitProfileId, nSection, 400, nGrpTmp) - EgtCutSurfTmPlane( nSplitSolid, EgtMP( tabSplits[i].nId), EgtIf( tabSplits[i].bStart, 1, -1) * EgtSV( tabSplits[i].nId)) + -- se sul lato corrente arrivano degli split con cambio profilo sull'estremo allora il lato deve essere forzato a cambio profilo + -- individuo i figli sugli estremi in base ai figli degli split che vi giacciono + if #vForcedCP[k] > 0 then + nPrfChange = nPrfChange + k + + -- verifico se gli split poggiano con lo start o con l'end sul lato corrente + local bStart = false + local vMixedPrev = EgtGetInfo( vForcedCP[k][1], WIN_MIXED_PREV, 'vi') + for j = 1, #vMixedPrev do + if abs( vMixedPrev[j]) == vSplits[i] then + bStart = true + break + end + end + + -- ordino gli split in base alla distanza dallo start + -- TODO caso non lineare + local vtDir = EgtSV( vSplits[i]) + local ptS = EgtSP( vSplits[i]) + local tabSplits = {} + for j = 1, #vForcedCP[k] do + local ptCurr = EgtIf( bStart, EgtSP( vForcedCP[k][j]), EgtEP( vForcedCP[k][j])) + local dDist = ( ptCurr - ptS) * vtDir + tabSplits[j] = { nId = vForcedCP[k][j], dDist = dDist} + end + table.sort( tabSplits, function ( a, b) return a.dDist < b.dDist end) + + -- il figlio sull'inizio è quello a destra del primo split, il figlio sulla fine è quello a sinistra dell'ultimo split + if k == 1 and bStart then + vStart[k] = EgtGetInfo( tabSplits[1].nId, WIN_MIXED_START_CHILDREN .. '1', 'i') + vEnd[k] = EgtGetInfo( tabSplits[#tabSplits].nId, WIN_MIXED_START_CHILDREN .. '2', 'i') + elseif k == 2 and not bStart then + vStart[k] = EgtGetInfo( tabSplits[1].nId, WIN_MIXED_END_CHILDREN .. '1', 'i') + vEnd[k] = EgtGetInfo( tabSplits[#tabSplits].nId, WIN_MIXED_END_CHILDREN .. '2', 'i') + + -- il figlio sull'inizio è quello a sinistra del primo split, il figlio sulla fine è quello a destra dell'ultimo split + elseif k == 1 and not bStart then + vStart[k] = EgtGetInfo( tabSplits[1].nId, WIN_MIXED_END_CHILDREN .. '2', 'i') + vEnd[k] = EgtGetInfo( tabSplits[#tabSplits].nId, WIN_MIXED_END_CHILDREN .. '1', 'i') + elseif k == 2 and bStart then + vStart[k] = EgtGetInfo( tabSplits[1].nId, WIN_MIXED_START_CHILDREN .. '2', 'i') + vEnd[k] = EgtGetInfo( tabSplits[#tabSplits].nId, WIN_MIXED_START_CHILDREN .. '1', 'i') + end + + + -- altrimenti se sul lato corrente non arriva nessuno split che determina un cambio profilo allora deve avere una sola tipologia di figli, + -- ma non è detto che la si possa cogliere correttamente guardando gli outlines figli. Recupero la tipologia guardando l'outline figlio più lungo + else + + local dSashLen = 0 + local dFillLen = 0 + local vCurrChildren = { vBaseChildren[k]} + local j = 1 + while vCurrChildren[j] do + local vNewChildren = EgtGetInfo( abs( vCurrChildren[j]), WIN_CHILD_VIRTUAL_OUTLINE, 'vi') + if vNewChildren then + EgtJoinTables( vCurrChildren, vNewChildren) + else + -- se non ha ulteriori figli allora è l'area null finale che deve essere studiata + local nNullAreaId = EgtGetParent( EgtGetParent( abs( vCurrChildren[j]))) + local nAreaId = EgtGetFirstNameInGroup( nNullAreaId, WIN_AREA .. '*') + if nAreaId then + local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') + if nAreaType == WIN_AREATYPES.SASH then + dSashLen = dSashLen + EgtCurveLength( abs( vCurrChildren[j])) + elseif nAreaType == WIN_AREATYPES.FILL then + dFillLen = dFillLen + EgtCurveLength( abs( vCurrChildren[j])) + end + end + end + j = j + 1 + end + + if dSashLen > dFillLen then + vStart[k] = WIN_CHILDREN_TYPES.SASH + vEnd[k] = WIN_CHILDREN_TYPES.SASH + else + vStart[k] = WIN_CHILDREN_TYPES.FILL + vEnd[k] = WIN_CHILDREN_TYPES.FILL + end + end + end + + -- verifico se cambio profilo sull'estremo + if vStart[1] ~= vStart[2] then + nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.START + end + if vEnd[1] ~= vEnd[2] then + nPrfChange = nPrfChange + WIN_PRF_CHANGE_TYPES.END + end + + -- aggiorno il profilo e la tipologia + if nPrfChange > 0 then + EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MIXED) + EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_MIXED_SPLIT) + EgtSetInfo( vSplits[i], WIN_PRF_CHANGE, nPrfChange) + EgtSetInfo( vSplits[i], WIN_MIXED_START_CHILDREN .. '1', vStart[1]) + EgtSetInfo( vSplits[i], WIN_MIXED_START_CHILDREN .. '2', vStart[2]) + EgtSetInfo( vSplits[i], WIN_MIXED_END_CHILDREN .. '1', vEnd[1]) + EgtSetInfo( vSplits[i], WIN_MIXED_END_CHILDREN .. '2', vEnd[2]) - -- testo con quali superfici degli outlines fa interferenza - for j = 1, #( tabSplits[i].vTest) do - local nIdx = tabSplits[i].vTest[j] - local nId, _, nCrvCnt = EgtSurfTmSurfTmInters( nSplitSolid, vTestSurfs[nIdx], nGrpTmp) - if nId and nCrvCnt > 0 then - vInterference[nIdx] = true - AddInfo( vOutlines[nIdx], WIN_CHILD_PRFCHANGE_SPLIT, tabSplits[i].nId) - AddInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_PREV_OUTLINES, WIN_NEXT_OUTLINES), vOutlines[nIdx]) - AddInfo( tabSplits[i].nId, EgtIf( tabSplits[i].bStart, WIN_STARTJOINT, WIN_ENDJOINT), WIN_PART_JNT.SHORT) + -- verifico quali pezzi saranno influenzati dal cambio profilo sull'estremo dello split corrente + if vStart[1] ~= vStart[2] or vEnd[1] ~= vEnd[2] then + VerifyProfileChangeSplitInterference( vSplits[i], tMixedProfiles, vStart[1] ~= vStart[2], vEnd[1] ~= vEnd[2]) + end + + else + local nOldType = EgtGetInfo( vSplits[i], WIN_SPLITTYPE, 'i') + -- se figli sono solo ante + if vStart[1] == WIN_CHILDREN_TYPES.SASH and nOldType ~= WIN_SPLITTYPES.MULLION then + EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MULLION) + if AreSameOrOppositeVectorApprox( EgtSV( vSplits[i]), X_AX()) then + EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_SASH_HORIZONTAL) + else + EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_SASH_VERTICAL) + end + + -- se figli sono solo vetri + elseif vStart[1] == WIN_CHILDREN_TYPES.FILL and nOldType ~= WIN_SPLITTYPES.MUNTIN_FRAME then + EgtSetInfo( vSplits[i], WIN_SPLITTYPE, WIN_SPLITTYPES.MUNTIN_FRAME) + EgtSetInfo( vSplits[i], WIN_PROFILETYPE, WIN_FRAME_SPLIT) end end end - - EgtErase( nGrpTmp) - return vInterference end --------------------------------------------------------------------- @@ -3025,13 +3206,10 @@ local function UpdateFrameTypes( nAreaId) local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) local vOutlines = EgtGetAllInGroup( nOutlineLayerId) - -- per ogni outline verifico se fa interferenza con uno split con cambio profilo sull'estremo - local vInterference = VerifyOutlinesInterferenceWithMixedSplit( nAreaId, vOutlines) - for i = 1, #vOutlines do local nOldType = EgtGetInfo( vOutlines[i], WIN_CHILDREN_TYPE, 'i') - - if vInterference[i] then + + if EgtExistsInfo( vOutlines[i], WIN_CHILD_PRFCHANGE_SPLIT) then -- se fa interferenza con uno split con cambio profilo sull'estremo deve avere un profilo mixed EgtSetInfo( vOutlines[i], WIN_PRF_CHANGE, WIN_PRF_CHANGE_TYPES.IN) -- verifico se devo aggiornare il profilo @@ -3044,10 +3222,8 @@ local function UpdateFrameTypes( nAreaId) end else - -- se non fa interferenza con cambio profilo devo controllare la tipologia dei figli. - -- Se non era stato classificato come mixed allora basta trovare la tipologia di un figlio qualunque, se invece era mixed allora ha entrambe le tipologie di figli, - -- devo considerare quella della curva più lunga ( euristicamente se non è più mixed vuol dire che il cambio profilo avviene vicino al suo estremo quindi - -- uno dei due figli è molto più corto dell'altro) + -- se non fa interferenza con cambio profilo devo controllare la tipologia dei figli. Potrebbe avere entrambe le tipologie di figli quindi devo considerare quella + -- della curva più lunga ( euristicamente se capita vuol dire che il cambio profilo avviene vicino al suo estremo quindi uno dei due figli è molto più corto dell'altro) local dFillLen = 0 local dSashLen = 0 local vChildren = EgtGetInfo( vOutlines[i], WIN_CHILD_VIRTUAL_OUTLINE, 'vi') @@ -3106,7 +3282,7 @@ end --------------------------------------------------------------------- -------------------------------------------------------------------- -local function CalcOutlineDimensions( vOutlines, nAreaId) +local function CalcOutlineDimensions( nAreaId, vOutlines) local vPartsDim = EgtGetInfo( nAreaId, WIN_PART_DIM, 'vd') or {} local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0 @@ -3137,24 +3313,18 @@ local function CalcOutlineDimensions( vOutlines, nAreaId) end --------------------------------------------------------------------- --- funzione che calcola l'outline dal base outline e i pezzi associati -local function CalculateOutlineFromAreaOutline( nAreaId) +-- funzione ricorsiva che calcola gli outlines delle aree di telaio e di split derivanti direttamente dal telaio +local function CalculateFrameAreasOutlines( nAreaId) local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') - -- se area null il suo outline è già stato calcolato dalla sua area split parent - if nAreaType == WIN_AREATYPES.NULL then - return - end - - -- creo gruppo per outline - local nOutlineLayerId = EgtGroup( nAreaId) - EgtSetName( nOutlineLayerId, WIN_OUTLINE) - EgtSetStatus( nOutlineLayerId, GDB_ST.OFF) - - -- FRAME + -- se area di telaio o split calcolo l'outline if nAreaType == WIN_AREATYPES.FRAME then - -- l'outline è la copia del base outline + + local nOutlineLayerId = EgtGroup( nAreaId) + EgtSetName( nOutlineLayerId, WIN_OUTLINE) + EgtSetStatus( nOutlineLayerId, GDB_ST.OFF) + local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) local vBaseOutlineIds = EgtGetAllInGroup( nBaseOutlineLayerId) local nBottomRail = EgtGetInfo( nAreaId, WIN_BOTTOMRAIL, 'i') or 0 @@ -3165,99 +3335,10 @@ local function CalculateOutlineFromAreaOutline( nAreaId) EgtSetInfo( vOutlines[i], WIN_BOTTOMRAIL, nBottomRail) end end - CalcOutlineDimensions( vOutlines, nAreaId) + CalcOutlineDimensions( nAreaId, vOutlines) - - -- SPLIT elseif nAreaType == WIN_AREATYPES.SPLIT then - - -- l'outline è copia del parent outline - local nParentId = EgtGetParent( nAreaId) - if EgtGetInfo( nParentId, WIN_AREATYPE, 'i') == WIN_AREATYPES.FILL then - -- se inglesina il parent è un vetro. Il pezzo però non va tagliato con il vetro ma con l'elemento che contiene il vetro, quindi considero come outline quello del parent del vetro - nParentId = EgtGetParent( nParentId) - end - local nParentOutlineId = EgtGetFirstNameInGroup( nParentId, WIN_OUTLINE) - local vParentOutlines = EgtGetAllInGroup( nParentOutlineId) - for i = 1, #vParentOutlines do - local nOutlineId = EgtCopyGlob( vParentOutlines[i], nOutlineLayerId) - EgtSetInfo( nOutlineId, WIN_SOU_OUTLINE, vParentOutlines[i]) - AddInfo( vParentOutlines[i], WIN_CHILD_VIRTUAL_OUTLINE, nOutlineId) - end - - -- copio il layer di base split - local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) - local nSplitLayerId = EgtCopy( nBaseSplitLayerId, nAreaId) - EgtSetName( nSplitLayerId, WIN_SPLIT) - EgtSetStatus( nSplitLayerId, GDB_ST.OFF) - local vBaseSplitIds = EgtGetAllInGroup( nBaseSplitLayerId) - local vSplitIds = EgtGetAllInGroup( nSplitLayerId) - - -- aggiusto la quota degli split per allinearli all'outline - local dZMove = ( EgtSP( vParentOutlines[1]) - EgtSP( vSplitIds[1])) * Z_AX() - EgtMove( vSplitIds, dZMove * Z_AX()) - - -- aggiusto gli outlines e calcolo l'outline delle sottoaree null generate - local bGrid = EgtGetInfo( nAreaId, WIN_GRID_SPLIT, 'b') or false - if bGrid then - CalculateGridSplitOutline( nAreaId, vSplitIds) - else - CalculateSplitOutline( nAreaId, vSplitIds) - end - - local nSplitType = EgtGetInfo( vSplitIds[1], WIN_SPLITTYPE, 'i') - - if nSplitType == WIN_SPLITTYPES.FRENCH then - IdentifySashShape( nAreaId, nOutlineLayerId) - end - - -- se inglesina su entrambi i lati creo copia degli outline per le inglesine esterne - if nSplitType == WIN_SPLITTYPES.MUNTIN_FILL then - local nMuntinType = EgtGetInfo( nAreaId, WIN_MUNTINFILL_SIDE, 'i') - if nMuntinType == WIN_MUNTINFILL_SIDES.BOTH then - local bSlide = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*'), WIN_SLIDE_WINDOW, 'b') or false - for i = 1, #vSplitIds do - local nId = EgtCopyGlob( vSplitIds[i], nSplitLayerId) - EgtSetInfo( vSplitIds[i], WIN_REF_MUNTIN, nId) - EgtSetInfo( vSplitIds[i], WIN_MUNTINFILL_SIDE, WIN_MUNTINFILL_SIDES.IN) - EgtSetInfo( nId, WIN_PROFILETYPE, EgtIf( bSlide, WIN_SLIDE .. '_', '') .. WIN_FILL_SPLIT_OUT) - EgtSetInfo( nId, WIN_MUNTINFILL_SIDE, WIN_MUNTINFILL_SIDES.OUT) - end - else - for i = 1, #vSplitIds do - EgtSetInfo( vSplitIds[i], WIN_MUNTINFILL_SIDE, nMuntinType) - end - end - end - - - -- SASH - elseif nAreaType == WIN_AREATYPES.SASH then - local nBaseOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) - local vOutlines = CalculateSashOutline( nAreaId, nBaseOutlineLayerId, nOutlineLayerId) - CalcOutlineDimensions( vOutlines, nAreaId) - -- ne verifico validità - VerifySashOutlines( vOutlines, nAreaId) - -- identifico la forma - IdentifySashShape( nAreaId, nOutlineLayerId) - -- disegno apertura - DrawOpening( nAreaId) - - - -- FILL - elseif nAreaType == WIN_AREATYPES.FILL then - CalculateFillOutline( nAreaId, nOutlineLayerId) - end -end - ---------------------------------------------------------------------- -local function CalculateFrameAreasOutlines( nAreaId) - - local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') - - -- se area di telaio o split calcolo l'outline - if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SPLIT then - CalculateOutlineFromAreaOutline( nAreaId) + CalcSplitAreaOutlines( nAreaId) -- se area anta o fill devo interrompere la ricerca elseif nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then @@ -3271,24 +3352,35 @@ local function CalculateFrameAreasOutlines( nAreaId) end --------------------------------------------------------------------- -local function CalculateResidualAreaOutlines( nAreaId) +-- funzione ricorsiva che calcola gli outlines delle aree fill, sash e split in esse contenute +local function CalculateFinalAreasOutlines( nAreaId) local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') - if nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.FILL then - CalculateOutlineFromAreaOutline( nAreaId) + if nAreaType == WIN_AREATYPES.SASH then + local vOutlines = CalculateSashAreaOutlines( nAreaId) + CalcOutlineDimensions( nAreaId, vOutlines) + -- ne verifico validità + VerifySashOutlines( nAreaId, vOutlines) + -- identifico la forma + IdentifySashShape( nAreaId, vOutlines) + -- disegno apertura + DrawOpening( nAreaId, vOutlines) + + elseif nAreaType == WIN_AREATYPES.FILL then + CalculateFillAreaOutlines( nAreaId) elseif nAreaType == WIN_AREATYPES.SPLIT then -- devo calcolarla solo se non è già stato fatto ( quindi non è uno split che dipende dal telaio) local nOutlineLayer = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) if not nOutlineLayer then - CalculateOutlineFromAreaOutline( nAreaId) + CalcSplitAreaOutlines( nAreaId) end end local vChildAreas = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') for i = 1, #vChildAreas do - CalculateResidualAreaOutlines( vChildAreas[i]) + CalculateFinalAreasOutlines( vChildAreas[i]) end end @@ -3299,7 +3391,7 @@ local function CalculateAreaOutline( nAreaId) CalculateFrameAreasOutlines( nAreaId) -- se cambio profilo lo spostamento degli split per le misure luce/esterno anta potrebbe aver modificato la tipologia dei figli delle curve del telaio e di altri split, - -- quindi la aggiorno in base agli outlines appena calcolati ( e non più rispetto ai base outlines) + -- quindi le aggiorno in base agli outlines appena calcolati ( e non più rispetto ai base outlines) local bChangeProfile = EgtGetInfo( nAreaId, WIN_MIXED_WINDOW, 'b') if bChangeProfile then UpdateSplitTypes( nAreaId) @@ -3307,7 +3399,7 @@ local function CalculateAreaOutline( nAreaId) end -- calcolo gli outlines delle ante, dei vetri e degli split in essi contenuti - CalculateResidualAreaOutlines( nAreaId) + CalculateFinalAreasOutlines( nAreaId) end --------------------------------------------------------------------- @@ -3414,6 +3506,43 @@ local function CalcPartJoint( nJointType, bHorizontal) end end +--------------------------------------------------------------------- +local function CheckProfileChangeOnCommonEdge( nCrv1, nCrv2) + -- verifico se il cambio profilo è sul punto di incontro tra le due curve quindi controllo se : + -- 1) hanno uno split con cambio profilo sull'estremo in comune + -- 2) sono relativi allo stesso estremo dello split + local vSplits1 = EgtGetInfo( nCrv1, WIN_CHILD_PRFCHANGE_SPLIT, 'vi') + local vSplits2 = EgtGetInfo( nCrv2, WIN_CHILD_PRFCHANGE_SPLIT, 'vi') + for i = 1, #vSplits1 do + for j = 1, #vSplits2 do + if vSplits1[i] == vSplits2[j] then + -- verifico se sono relativi allo stesso estremo + local vPrev = EgtGetInfo( vSplits1[i], WIN_MIXED_PREV, 'vi') or {} + local nCnt = 0 + for k = 1, #vPrev do + if abs( vPrev[k]) == nCrv1 or abs( vPrev[k]) == nCrv2 then + nCnt = nCnt + 1 + end + end + if nCnt == 2 then + return true + end + local vNext = EgtGetInfo( vSplits1[i], WIN_MIXED_NEXT, 'vi') or {} + nCnt = 0 + for k = 1, #vNext do + if abs( vNext[k]) == nCrv1 or abs( vNext[k]) == nCrv2 then + nCnt = nCnt + 1 + end + end + if nCnt == 2 then + return true + end + end + end + end + return false +end + --------------------------------------------------------------------- local function CalcOutlineStartJoint( nOutlineId, nPrevOutlineId, vJoints) @@ -3450,15 +3579,8 @@ local function CalcOutlineStartJoint( nOutlineId, nPrevOutlineId, vJoints) local nProfileChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') local nProfileChangeP = EgtGetInfo( nPrevOutlineId, WIN_PRF_CHANGE, 'i') if nProfileChange == WIN_PRF_CHANGE_TYPES.IN and nProfileChangeP == WIN_PRF_CHANGE_TYPES.IN then - -- per vedere se il cambio profilo è sul punto di incontro verifico se hanno uno split con cambio profilo sull'estremo in comune - local vSplits1 = EgtGetInfo( nOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi') - local vSplits2 = EgtGetInfo( nPrevOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi') - for i = 1, #vSplits1 do - for j = 1, #vSplits2 do - if vSplits1[i] == vSplits2[j] then - return WIN_PART_JNT.ANGLED - end - end + if CheckProfileChangeOnCommonEdge( nOutlineId, nPrevOutlineId) then + nStartJoint = WIN_PART_JNT.ANGLED end end @@ -3501,15 +3623,8 @@ local function CalcOutlineEndJoint( nOutlineId, nNextOutlineId, vJoints) local nProfileChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') local nProfileChangeN = EgtGetInfo( nNextOutlineId, WIN_PRF_CHANGE, 'i') if nProfileChange == WIN_PRF_CHANGE_TYPES.IN and nProfileChangeN == WIN_PRF_CHANGE_TYPES.IN then - -- per vedere se il cambio profilo è sul punto di incontro verifico se hanno uno split con cambio profilo sull'estremo in comune - local vSplits1 = EgtGetInfo( nOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi') - local vSplits2 = EgtGetInfo( nNextOutlineId, WIN_CHILD_PRFCHANGE_SPLIT, 'vi') - for i = 1, #vSplits1 do - for j = 1, #vSplits2 do - if vSplits1[i] == vSplits2[j] then - return WIN_PART_JNT.ANGLED - end - end + if CheckProfileChangeOnCommonEdge( nOutlineId, nNextOutlineId) then + nEndJoint = WIN_PART_JNT.ANGLED end end @@ -3790,7 +3905,7 @@ local function TestSplitTrimOutlines( nOutlineId, nSplitType, nTrimOutline, tabO local vsCtrIn = {} for i = 1, #vTestOutlines do vProfiles[i] = vTestOutlines[i].nProfile - vsCtrIn[i] = GetProfileCtrIn( vTestOutlines[i].nId, nOutlineId, vProfiles[i], bPrevOrNext) + vsCtrIn[i] = GetProfileCtrIn( vTestOutlines[i].nId, nOutlineId, bPrevOrNext) end -- testo le curve @@ -3850,29 +3965,25 @@ local function GetSplitsPrevNextOutline( vSplitIds, vOutlineIds) local nSplitType = EgtGetInfo( vSplitIds[i], WIN_SPLITTYPE, 'i') -- prev - if not EgtExistsInfo( vSplitIds[i], WIN_PREV_OUTLINES) then - local nPrevOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_STARTINTERS, 'i') - local vPrevOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nSplitType, nPrevOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, true) - EgtSetInfo( vSplitIds[i], WIN_PREV_OUTLINES, vPrevOutlineIds) - -- setto tutte le giunzioni a short - local vStartJoints = {} - for j = 1, #vPrevOutlineIds do - vStartJoints[j] = WIN_PART_JNT.SHORT - end - EgtSetInfo( vSplitIds[i], WIN_STARTJOINT, vStartJoints) + local nPrevOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_STARTINTERS, 'i') + local vPrevOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nSplitType, nPrevOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, true) + EgtSetInfo( vSplitIds[i], WIN_PREV_OUTLINES, vPrevOutlineIds) + -- setto tutte le giunzioni a short + local vStartJoints = {} + for j = 1, #vPrevOutlineIds do + vStartJoints[j] = WIN_PART_JNT.SHORT end + EgtSetInfo( vSplitIds[i], WIN_STARTJOINT, vStartJoints) -- next - if not EgtExistsInfo( vSplitIds[i], WIN_NEXT_OUTLINES) then - local nNextOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_ENDINTERS, 'i') - local vNextOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nSplitType, nNextOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, false) - EgtSetInfo( vSplitIds[i], WIN_NEXT_OUTLINES, vNextOutlineIds) - local vEndJoints = {} - for j = 1, #vNextOutlineIds do - vEndJoints[j] = WIN_PART_JNT.SHORT - end - EgtSetInfo( vSplitIds[i], WIN_ENDJOINT, vEndJoints) + local nNextOutlineId = EgtGetInfo( vSplitIds[i], WIN_SPLIT_ENDINTERS, 'i') + local vNextOutlineIds = TestSplitTrimOutlines( vSplitIds[i], nSplitType, nNextOutlineId, tabOutlines, nMainProfile, b3Profile, nGrpTmp, false) + EgtSetInfo( vSplitIds[i], WIN_NEXT_OUTLINES, vNextOutlineIds) + local vEndJoints = {} + for j = 1, #vNextOutlineIds do + vEndJoints[j] = WIN_PART_JNT.SHORT end + EgtSetInfo( vSplitIds[i], WIN_ENDJOINT, vEndJoints) end EgtErase( nGrpTmp) @@ -4043,7 +4154,7 @@ local function GetAreaPrevNextOutlines( nAreaId) vSplits = vInSplits end - -- se split a griglia + -- se split a griglia local bGrid = EgtGetInfo( nAreaId, WIN_GRID_SPLIT, 'b') or false if bGrid then local vVirtualAreas = EgtGetNameInGroup( nAreaId, WIN_VIRTUAL_AREA) @@ -4153,12 +4264,12 @@ local function CalcGeoRegion( vCrvs, nGrp) local ptM = EgtMP( nRefOutline) local _, _, dPar1 = EgtPointCurveDist( ptM, tArcs[j].nCrvId) local _, _, dPar2 = EgtPointCurveDist( ptM, nCrvId) - EgtTrimCurveStartAtParam( nCrvId, dPar2) - EgtTrimCurveEndAtParam( tArcs[j].nCrvId, dPar1) + EgtTrimCurveStartAtParam( tArcs[j].nCrvId, dPar1) + EgtTrimCurveEndAtParam( nCrvId, dPar2) local nNewExt = EgtCurveCompo( nGrpTmp, nCrvId) EgtAddCurveCompoLine( nNewExt, EgtSP( tArcs[j].nCrvId)) EgtAddCurveCompoCurve( nNewExt, tArcs[j].nCrvId) - + tArcs[j].nCrvId = nNewExt table.insert( tArcs[j].vOrigId, vCrvs[i]) bFound = true @@ -4217,27 +4328,8 @@ local function CalcGeoRegion( vCrvs, nGrp) nCnt = nCnt - 1 end - -- spezzo in corrispondenza di eventuali punti tangenti alla regione - local vArcs = EgtTableFill( nCrv, nCnt) - for j = nCrv, nCrv + nCnt - 1 do - local nInters, nPntCnt, nCrvCnt = EgtCurveCurveInters( j, nCrvBorder, nGrpTmp) - if nInters then - if nCnt == 1 then - EgtChangeClosedCurveStartPoint( j, EgtSP( nInters)) - end - local nCurrCrv = j - for nPntId = nInters, nInters + nPntCnt - 1 do - local dPar = EgtCurveParamAtPoint( nCurrCrv, EgtSP( nPntId)) - local nNewCrv = EgtSplitCurveAtParam( nCurrCrv, dPar) - if nNewCrv then - table.insert( vArcs, nNewCrv) - nCurrCrv = nNewCrv - end - end - end - end - -- modifico il bordo corrente considerando solo i tratti che poggiano sulle curve orginali + local vArcs = EgtTableFill( nCrv, nCnt) for j = 1, #vArcs do for k = 1, #tArcs[i].vOrigId do if CheckExtensionOverlap( vArcs[j], tArcs[i].vOrigId[k]) then @@ -4305,22 +4397,37 @@ local function CheckSemiprofileIntersection( nGeoId, nPrevGeoId, nNextGeoId) local nOutlineId = EgtGetInfo( nGeoId, WIN_REF_OUTLINE, 'i') - -- recupero la curva più interna del semiprofilo + -- recupero le curve di bordo della lavorazione + local dGeoOffs = EgtGetInfo( nGeoId, WIN_GEO_OFFS, 'd') local nSemiProfileId = EgtGetInfo( nGeoId, WIN_SEMI_PROFILE, 'i') local nProfileId = EgtGetParent( nSemiProfileId) local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frFrame = EgtFR( nFrameId, GDB_ID.ROOT) local b3Box = EgtGetBBoxRef( nSemiProfileId, GDB_BB.STANDARD, frFrame) - local nInnerCrv = EgtCopyGlob( nOutlineId, EgtGetParent( nGeoId)) - EgtOffsetCurve( nInnerCrv, b3Box:getMin():getX()) + local nInnerCrv1 = EgtCopyGlob( abs( nOutlineId), EgtGetParent( nGeoId)) + local nInnerCrv2 = EgtCopyGlob( abs( nOutlineId), EgtGetParent( nGeoId)) + if nOutlineId < 0 then + EgtInvertCurve( nInnerCrv1) + EgtInvertCurve( nInnerCrv2) + end + EgtOffsetCurve( nInnerCrv1, dGeoOffs) + EgtOffsetCurve( nInnerCrv2, dGeoOffs - b3Box:getDimX()) + + -- la curva più problematica è quella con raggio minore + local nInnerCrv = nInnerCrv2 + if EgtArcRadius( nInnerCrv1) < EgtArcRadius( nInnerCrv2) then + nInnerCrv = nInnerCrv1 + end + -- verifico se con estensione standard ( ovvero seguendo la circonferenza associata) arriva alle curve vicine del geo local ptInt1 = FindIntersectionPoint( nInnerCrv, nPrevGeoId, ORIG()) local bTangStart = ( not ptInt1) local ptInt2 = FindIntersectionPoint( nInnerCrv, nNextGeoId, ORIG()) local bTangEnd = ( not ptInt2) - - EgtErase( nInnerCrv) + + EgtErase( nInnerCrv1) + EgtErase( nInnerCrv2) return bTangStart, bTangEnd end @@ -4336,17 +4443,15 @@ local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, vStartJ -- se il pezzo corrente è arco devo verificare estensione per in e out if EgtGetType( nOutId) == GDB_TY.CRV_ARC then - local bTangStart, bTangEnd = CheckSemiprofileIntersection( nOutId, vLeftIds[#vLeftIds], vRightIds[1]) - -- verifico se necessaria estensione in tangenza per giunzione angled o per la curva in - if not bTangStart then - bTangStart = ( vStartJoints[#vStartJoints] == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vLeftIds[1], ORIG())) - end + local bTangStart1, bTangEnd1 = CheckSemiprofileIntersection( nOutId, vLeftIds[#vLeftIds], vRightIds[1]) + local bTangStart2, bTangEnd2 = CheckSemiprofileIntersection( nInId, vLeftIds[1], vRightIds[#vRightIds]) + + -- verifico se necessaria estensione in tangenza per curve in/out o per giunzione angled + local bTangStart = ( bTangStart1 or bTangStart2 or vStartJoints[#vStartJoints] == WIN_PART_JNT.ANGLED) EgtSetInfo( nOutId, WIN_TANG_START, bTangStart) EgtSetInfo( nInId, WIN_TANG_END, bTangStart) - - if not bTangEnd then - bTangEnd = ( vEndJoints[1] == WIN_PART_JNT.ANGLED or not FindIntersectionPoint( nInId, vRightIds[#vRightIds], ORIG())) - end + + local bTangEnd = ( bTangEnd1 or bTangEnd2 or vEndJoints[1] == WIN_PART_JNT.ANGLED) EgtSetInfo( nOutId, WIN_TANG_END, bTangEnd) EgtSetInfo( nInId, WIN_TANG_START, bTangEnd) end @@ -4358,14 +4463,14 @@ local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, vStartJ -- se outline in tangenza con i vicini forzo estensione in tangenza if not bTangS then - local nOutlineId = EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i') + local nOutlineId = abs( EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i')) local nPrevOutlineId = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId)) if AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then bTangS = true end end if not bTangE then - local nOutlineId = EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i') + local nOutlineId = abs( EgtGetInfo( vLeftIds[i], WIN_REF_OUTLINE, 'i')) local nNextOutlineId = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId)) if AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then bTangE = true @@ -4383,14 +4488,14 @@ local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, vStartJ local bTangS, bTangE = CheckSemiprofileIntersection( vRightIds[i], nOutId, nInId) if not bTangS then - local nOutlineId = EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i') + local nOutlineId = abs( EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i')) local nPrevOutlineId = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId)) if AreSameVectorApprox( EgtEV( nPrevOutlineId), EgtSV( nOutlineId)) then bTangS = true end end if not bTangE then - local nOutlineId = EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i') + local nOutlineId = abs( EgtGetInfo( vRightIds[i], WIN_REF_OUTLINE, 'i')) local nNextOutlineId = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId)) if AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( nNextOutlineId)) then bTangE = true @@ -4403,6 +4508,52 @@ local function ComputeArcExtensions( nOutId, nInId, vLeftIds, vRightIds, vStartJ end end +--------------------------------------------------------------------- +local function AddSemiProfile( sSouName, nDestProfile, nOutlineId) + + local sProfile = WIN_MIXED_TOP + if EgtGetName( abs( nOutlineId)) == WIN_SPLIT then + sProfile = WIN_MIXED_SPLIT + elseif EgtGetName( abs( nOutlineId)) == WIN_BOTTOM then + sProfile = WIN_MIXED_BOTTOM + end + local nPrfGrp = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) + local nPrfFrameGrp = EgtGetFirstNameInGroup( nPrfGrp, WIN_FRAME) + local nSouProfile = EgtGetFirstNameInGroup( nPrfFrameGrp, sProfile) + + -- copio il controprofilo e il suo offset + local nSou = EgtGetFirstNameInGroup( nSouProfile, sSouName) + local nSou2 = EgtGetFirstNameInGroup( nSouProfile, WIN_OFST .. sSouName) + local nCopy = EgtCopyGlob( nSou, nDestProfile) + local nCopy2 = EgtCopyGlob( nSou2, nDestProfile) + + -- lo posiziono nel nuovo profilo tenendo conto che i due profili potrebbero essere orientati in modo diverso + local nSouFrame = EgtGetFirstNameInGroup( nSouProfile, WIN_SECTIONFRAME) + local frSou = EgtFR( nSouFrame, GDB_ID.ROOT) + frSou:invert() + local nDestFrame = EgtGetFirstNameInGroup( nDestProfile, WIN_SECTIONFRAME) + local frDest = EgtFR( nDestFrame, GDB_ID.ROOT) + EgtTransform( nCopy, frSou) + EgtTransform( nCopy, frDest) + EgtTransform( nCopy2, frSou) + EgtTransform( nCopy2, frDest) + + -- aggiusto la posizione in base alle dimensioni reali del pezzo + local nRefId = EgtGetFirstNameInGroup( nDestProfile, WIN_REF) + local b3BoxProfile = EgtGetBBoxRef( nRefId, GDB_BB.STANDARD, frDest) + local b3Box = EgtGetBBoxRef( nCopy, GDB_BB.STANDARD, frDest) + local vtMove + if nOutlineId > 0 then + vtMove = ( b3BoxProfile:getMin():getX() - b3Box:getMin():getX()) * frDest:getVersX() + else + vtMove = ( b3BoxProfile:getMax():getX() - b3Box:getMax():getX()) * frDest:getVersX() + end + EgtMove( nCopy, vtMove, GDB_RT.GLOB) + EgtMove( nCopy2, vtMove, GDB_RT.GLOB) + + return nCopy +end + --------------------------------------------------------------------- -- funzione che crea le curve del geo local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vStartJoints, vEndJoints, nGeoLayerId, nProfileLayerId) @@ -4479,13 +4630,15 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vSta -- b) se profili diversi per taglio corretto dei profili serve considerare anche il bordo out del pezzo adiacente local sCurrProfile = EgtGetInfo( nCurrProfileId, WIN_PROFILETYPE) local sPrevProfile = EgtGetInfo( vPrevProfileId[i], WIN_PROFILETYPE) - if sCurrProfile ~= sPrevProfile and not AreSameVectorApprox( EgtSV( nOutlineId), EgtEV( vPrevOutlineId[i])) then + if sCurrProfile ~= sPrevProfile and EgtEV( vPrevOutlineId[i]) * EgtSV( nOutlineId) < s_dAngledCos then EgtSetName( nOtherOut, WIN_GEO_LEFT) EgtRelocateGlob( nOtherOut, nGeoLayerId, GDB_IN.LAST_SON) local nSemiProfileId = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT) EgtSetInfo( nOtherOut, WIN_SEMI_PROFILE, nSemiProfileId) EgtSetInfo( nOtherOut, WIN_REF_OUTLINE, vPrevOutlineId[i]) EgtSetInfo( nOtherOut, WIN_GEO_OFFS, b3Profile:getMax():getX()) + elseif EgtGetType( nBisector) == GDB_TY.CRV_LINE then + EgtErase( nOtherOut) else -- considero la curva out come curva ausiliaria per il calcolo del geo EgtSetName( nOtherOut, WIN_AUX) @@ -4499,18 +4652,37 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vSta EgtInvertCurve( nPrevCurveId) end local dOffs, nPrevSemiProfile + if vStartJoints[i] == WIN_PART_JNT.SHORT then -- la curva del geo corrisponde al bordo del controprofilo in del pezzo vicino - local sCtrIn = GetProfileCtrIn( vPrevOutlineId[i], nOutlineId, vPrevProfileId[i], true) + -- se cambio profilo sullo start devo tagliare sempre con il controprofilo sash del pezzo vicino, anche se non fosse presente nel profilo + local sCtrIn + local nPrfChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL + if nPrfChange & WIN_PRF_CHANGE_TYPES.START == 0 then + sCtrIn = GetProfileCtrIn( vPrevOutlineId[i], nOutlineId, true) + else + sCtrIn = WIN_SASH .. WIN_CTRIN + if EgtGetName( abs( vPrevOutlineId[i])) == WIN_SPLIT then + sCtrIn = sCtrIn .. EgtIf( vPrevOutlineId[i] < 0, '1', '2') + end + end + + nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], sCtrIn) + if not nPrevSemiProfile then + -- se il pezzo contro cui finisce non è di cambio profilo, devo recuperare il semiprofilo sash da un profilo mixed teorico e aggiungerlo + nPrevSemiProfile = AddSemiProfile( sCtrIn, vPrevProfileId[i], vPrevOutlineId[i]) + end + local dCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn, vPrevOutlineId[i]) dOffs = - dCPDelta - nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], sCtrIn) + else -- la curva del geo corrisponde all'out del pezzo vicino local b3Profile = GetProfileLocalBox( vPrevProfileId[i]) dOffs = b3Profile:getMax():getX() nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT) end + EgtOffsetCurve( nPrevCurveId, dOffs) EgtSetInfo( nPrevCurveId, WIN_GEO_OFFS, dOffs) EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile) @@ -4552,13 +4724,15 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vSta -- gestione per profili diversi local sCurrProfile = EgtGetInfo( nCurrProfileId, WIN_PROFILETYPE) local sNextProfile = EgtGetInfo( vNextProfileId[i], WIN_PROFILETYPE) - if sCurrProfile ~= sNextProfile and not AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( vNextOutlineId[i])) then + if sCurrProfile ~= sNextProfile and EgtEV( nOutlineId) * EgtSV( vNextOutlineId[i]) < s_dAngledCos then EgtSetName( nOtherOut, WIN_GEO_RIGHT) local nSemiProfileId = EgtGetFirstNameInGroup( vNextProfileId[i], WIN_OUT) EgtSetInfo( nOtherOut, WIN_SEMI_PROFILE, nSemiProfileId) EgtSetInfo( nOtherOut, WIN_REF_OUTLINE, vNextOutlineId[i]) EgtSetInfo( nOtherOut, WIN_GEO_OFFS, b3Profile:getMax():getX()) EgtRelocateGlob( nOtherOut, nInId, GDB_IN.BEFORE) + elseif EgtGetType( nBisector) == GDB_TY.CRV_LINE then + EgtErase( nOtherOut) else EgtSetName( nOtherOut, WIN_AUX) EgtSetInfo( nOtherOut, WIN_TANG_START, true) @@ -4571,16 +4745,35 @@ local function CreateGeoCurves( nOutlineId, vPrevOutlineId, vNextOutlineId, vSta EgtInvertCurve( nNextCurveId) end local dOffs, nNextSemiProfile + + -- se ha cambio profilo sull'end deve essere tagliato con i controprofili sash di tutti i suoi next anche se potrebbero non essere presenti nel loro profilo if vEndJoints[i] == WIN_PART_JNT.SHORT then - local sCtrIn = GetProfileCtrIn( vNextOutlineId[i], nOutlineId, vNextProfileId[i], false) + local sCtrIn + local nPrfChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL + if nPrfChange & WIN_PRF_CHANGE_TYPES.END == 0 then + sCtrIn = GetProfileCtrIn( vNextOutlineId[i], nOutlineId, false) + else + sCtrIn = WIN_SASH .. WIN_CTRIN + if EgtGetName( abs( vNextOutlineId[i])) == WIN_SPLIT then + sCtrIn = sCtrIn .. EgtIf( vNextOutlineId[i] < 0, '1', '2') + end + end + + nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], sCtrIn) + if not nNextSemiProfile then + -- se il pezzo contro cui finisce non è di cambio profilo, devo recuperare il semiprofilo sash da un profilo mixed teorico e aggiungerlo + nNextSemiProfile = AddSemiProfile( sCtrIn, vNextProfileId[i], vNextOutlineId[i]) + end + local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn, vNextOutlineId[i]) dOffs = - dCPDelta - nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], sCtrIn) + else local b3Profile = GetProfileLocalBox( vNextProfileId[i]) dOffs = b3Profile:getMax():getX() nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], WIN_OUT) end + EgtOffsetCurve( nNextCurveId, dOffs) EgtSetInfo( nNextCurveId, WIN_GEO_OFFS, dOffs) EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile) @@ -4721,8 +4914,6 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit local nGrpTmp = EgtGroup( nGrp) - local dDim1 = 61 - local dDim2 = 45 local dRad = EgtGetInfo( nSplitProfileId, WIN_RAD_REF .. '1', 'd') local ptRef = EgtIf( bStart, EgtSP( nSplitId), EgtEP( nSplitId)) @@ -4730,20 +4921,16 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit local b3SplitProfile = GetProfileLocalBox( nSplitProfileId) local dSplitFixedOverl = EgtGetInfo( nSplitProfileId, WIN_FIXED_REF, 'd') local dSplitSashOverl1 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '1', 'd') - local dSplitSashOverl2 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd') - local nCrvSF, nCrvSS1, nCrvSS2 + local nCrvSF, nCrvSS1 if bFillOnRight then nCrvSF = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMax():getX() - dSplitFixedOverl) nCrvSS1 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitSashOverl1) - nCrvSS2 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitSashOverl2) else nCrvSF = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMin():getX() + dSplitFixedOverl) nCrvSS1 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMax():getX() - dSplitSashOverl1) - nCrvSS2 = EgtOffsetCurveAdv( nSplitId, b3SplitProfile:getMax():getX() - dSplitSashOverl2) end EgtRelocateGlob( nCrvSF, nGrpTmp) EgtRelocateGlob( nCrvSS1, nGrpTmp) - EgtRelocateGlob( nCrvSS2, nGrpTmp) -- calcolo le curve di riferimento prev local vCompoOutlines = {} @@ -4765,7 +4952,8 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit local dFrameExtra = EgtGetInfo( nOutlineProfileId, WIN_EXTRA_DIST, 'd') local nCrvFIn = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOverl2 + dFrameExtra) - local dDepth = EgtGetInfo( nOutlineProfileId, WIN_SASH_DEPTH .. '2', 'd') + local dDepth1 = EgtGetInfo( nOutlineProfileId, WIN_SASH_DEPTH .. '1', 'd') + local dDepth2 = EgtGetInfo( nOutlineProfileId, WIN_SASH_DEPTH .. '2', 'd') -- calcolo il bisettore a partire dall'incontro delle parti fixed del telaio e dello split local nBisector @@ -4775,9 +4963,11 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit if EgtCurveCompoRadius( nCrvFF, nCrvRef) == -1 then -- se l'incontro tra la parte fixed del telaio e dello split avviene su un tratto lineare il bisettore è linea - local vtDir = ( EgtUV( nCrvFF, dParRef, -1) + EgtSV( nSplitId)) - if not bFillOnRight then - vtDir = ( EgtUV( nCrvFF, dParRef, -1) - EgtSV( nSplitId)) + local vtDir = EgtUV( nCrvFF, dParRef, -1) + if bFillOnRight then + vtDir = vtDir + EgtSV( nSplitId) + else + vtDir = vtDir - EgtSV( nSplitId) end nBisector = EgtLinePVL( nGrpTmp, pt1, vtDir, 1000) EgtExtendCurveStartByLen( nBisector, 1000) @@ -4804,14 +4994,16 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit end -- posizione finale del tool di profilatura che determina il limite delle fresature - local nBisectTool = EgtCopyGlob( nBisector, nGrpTmp) - EgtOffsetCurve( nBisectTool, - dDim1 * 0.5) + local dDiam1 = EgtGetInfo( nOutlineProfileId, WIN_SASH_DIAM .. '1', 'd') + local dDiam2 = EgtGetInfo( nOutlineProfileId, WIN_SASH_DIAM .. '2', 'd') + local nBisectTool = EgtCopyGlob( nBisector, nGrp) + EgtOffsetCurve( nBisectTool, - dDiam1 * 0.5) EgtExtendCurveStartByLen( nBisectTool, 10) EgtExtendCurveEndByLen( nBisectTool, 10) - local nCrvSash = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOverl1 - dDim1 * 0.5) + local nCrvSash = EgtOffsetCurveAdv( nOutlineCompo, b3FrameProfile:getMin():getX() + dFrameSashOverl1 - dDiam1 * 0.5) local ptEnd = EgtIP( nCrvSash, nBisectTool, ptRef) - local nCircle = EgtCircle( nGrpTmp, ptEnd, dDim1 * 0.5) - local nCircle2 = EgtCircle( nGrpTmp, ptEnd, dDim2 * 0.5) + local nCircle = EgtCircle( nGrpTmp, ptEnd, dDiam1 * 0.5) + local nCircle2 = EgtCircle( nGrpTmp, ptEnd, dDiam2 * 0.5) -- 1) Fresatura #1 @@ -4836,12 +5028,13 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit EgtRelocateGlob( nMilling, nGrp) EgtSetColor( nMilling, EgtStdColor( 'BLUE')) EgtSetName( nMilling, WIN_MIXED_MILLING .. '1') - EgtSetInfo( nMilling, WIN_MIXED_SPLIT_REF, nSplitId) EgtModifyCurveExtrusion( nMilling, Z_AX()) - EgtModifyCurveThickness( nMilling, - dDepth) + EgtModifyCurveThickness( nMilling, - dDepth1) - EgtSetInfo( nMilling, WIN_FILL_ON_SPLIT_RIGHT, bFillOnRight) - + EgtSetInfo( nMilling, WIN_MIXED_SPLIT_REF, nSplitId) + EgtSetInfo( nMilling, WIN_MIXED_SASHFILL, bSashFill) + EgtSetInfo( nMilling, WIN_MIXED_ONSTART, bStart) + EgtSetInfo( nMilling, WIN_MIXED_BISECTOR_REF, nBisectTool) -- 2) Fresatura #2 -- calcolo i punti di riferimento @@ -4849,7 +5042,7 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit local pt4 = EgtIP( nCrvFIn, nCrvSS1, ptRef) local pt5 = EgtIP( nCrvSS1, nCrvFS2, ptRef) -- calcolo le curve - local dParA = EgtCurveParamAtPoint( nBisector, EgtIf( bSashFill, EgtEP( nMilling), EgtSP( nMilling))) + local dParA = EgtCurveParamAtPoint( nBisector, pt1) local dParB = EgtCurveParamAtPoint( nBisector, pt3) local nMill3 = EgtCopyParamRange( nBisector, min( dParA, dParB), max( dParA, dParB), nGrpTmp) local dParC = EgtCurveParamAtPoint( nCrvFIn, pt3) @@ -4879,7 +5072,8 @@ local function CalcMixedMillings( vOutlines, nOutlineProfileId, nSplitId, nSplit EgtSetColor( nMilling2, EgtStdColor( 'BLUE')) EgtSetName( nMilling2, WIN_MIXED_MILLING .. '2') EgtModifyCurveExtrusion( nMilling2, Z_AX()) - EgtModifyCurveThickness( nMilling2, - dDepth) + EgtMove( nMilling2, - dDepth1 * Z_AX()) + EgtModifyCurveThickness( nMilling2, - ( dDepth2 - dDepth1)) -- taglio sul punto finale della lavorazione di profilatura local pt6 = EgtIP( nMilling2, nCircle2, ptRef) @@ -4912,7 +5106,7 @@ local function CalcMixedCurves( nPartId, nSplitId) -- start -- se cambio profilo sull'estremo start allora serve fresatura per cambio profilo if nPrfChange & WIN_PRF_CHANGE_TYPES.START > 0 then - local vPrevOutlines = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi') + local vPrevOutlines = EgtGetInfo( nSplitId, WIN_MIXED_PREV, 'vi') local nPrevProfileId = GetOutlineProfileId( abs( vPrevOutlines[1])) -- verifico se lungo la direzione del prev outline l'ordine è sash/fill ( true) o fill/sash ( false) local nStart1 = EgtGetInfo( nSplitId, WIN_MIXED_START_CHILDREN .. '1', 'i') @@ -4941,7 +5135,7 @@ local function CalcMixedCurves( nPartId, nSplitId) -- end if nPrfChange & WIN_PRF_CHANGE_TYPES.END > 0 then - local vNextOutlines = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi') + local vNextOutlines = EgtGetInfo( nSplitId, WIN_MIXED_NEXT, 'vi') local nNextProfileId = GetOutlineProfileId( abs( vNextOutlines[1])) -- verifico se lungo la direzione del next outline l'ordine è sash/fill ( true) o fill/sash ( false) local nEnd1 = EgtGetInfo( nSplitId, WIN_MIXED_END_CHILDREN .. '1', 'i') @@ -4963,7 +5157,7 @@ local function CalcMixedCurves( nPartId, nSplitId) local nCrv2 = EgtCopyGlob( nMill4, nMixedInters) local sSide = EgtIf( vNextOutlines[i] > 0, WIN_IN, WIN_OUT) EgtSetName( nCrv1, WIN_MIXED_MILLING .. sSide .. '1') - EgtSetName( nCrv2, WIN_MIXED_MILLING .. sSide .. '2') + EgtSetName( nCrv2, WIN_MIXED_MILLING .. sSide .. '2') end end end @@ -4979,18 +5173,15 @@ local function GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile) if nSemiProfile then -- setto info di lavorazione EgtSetInfo( nCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) - -- setto info con il tipo di profiling + -- setto info con il tipo di profiling e la fase ( solo se in o out) local sName = EgtGetName( nCrv) if sName == WIN_GEO_LEFT or sName == WIN_GEO_RIGHT then EgtSetInfo( nCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.HEAD) else EgtSetInfo( nCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.LONGITUDINAL) - end - -- recupero le info di lavorazione dal semiprofilo - if sName == WIN_GEO_OUT or sName == WIN_GEO_IN then - -- recupero la fase solo se si tratta di in o out CopyInfo( nCrv, nSemiProfile, WIN_PRC_PHASE) end + local nTools = EgtGetInfo( nSemiProfile, WIN_PRC_NTOOLS , 'i') or 0 EgtSetInfo( nCrv, WIN_PRC_NTOOLS, nTools) for j = 1, nTools do @@ -5259,7 +5450,6 @@ local function CreateProfilingProcessingCurve( nGeoCrvId, nPrevCrv, nSurfGeo, nP EgtAddCurveCompoCurve( nPrcCrvId, nNewCrv) end end - end end EgtErase( nGrpTmp) @@ -5288,9 +5478,19 @@ local function TrimTangentProcessings( nPrc1, nPrc2, ptRef) if ptInt then local dPar1 = EgtCurveParamAtPoint( nPrc1, ptInt) local dPar2 = EgtCurveParamAtPoint( nPrc2, ptInt) - if AreSameVectorApprox( EgtUV( nPrc1, dPar1, -1), EgtUV( nPrc2, dPar2, -1)) then - EgtTrimCurveEndAtParam( nPrc1, dPar1) - EgtTrimCurveStartAtParam( nPrc2, dPar2) + if AreSameVectorApprox( EgtUV( nPrc1, dPar1, 1), EgtUV( nPrc2, dPar2, -1)) then + if dPar1 < GEO.EPS_SMALL then + EgtErase( nPrc1) + else + EgtTrimCurveEndAtParam( nPrc1, dPar1) + end + + local _, dE = EgtCurveDomain( nPrc2) + if abs( dPar2 - dE) < GEO.EPS_SMALL then + EgtErase( nPrc2) + else + EgtTrimCurveStartAtParam( nPrc2, dPar2) + end end end end @@ -5298,18 +5498,18 @@ end --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profilatura a partire dalle curve del geo -local function CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLayerId, nPartId) +local function CreateProfilingProcessingFromGeo( nPartId, nGeoLayerId, nGeoSurfId, nPrcLayerId) -- a) out local nOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) - local nPrcOut = CreateProfilingProcessingCurve( nOut, nil, nSurfGeo, nProcLayerId) + local nPrcOut = CreateProfilingProcessingCurve( nOut, nil, nGeoSurfId, nPrcLayerId) local sOutId = EgtGetInfo( nPrcOut, WIN_PRC_ID) EgtSetInfo( nPartId, WIN_PRC_PROFILE_OUT, sOutId) -- b) in local nIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) - local nPrcIn = CreateProfilingProcessingCurve( nIn, nil, nSurfGeo, nProcLayerId) - local sInId = EgtGetInfo( nPrcIn, WIN_PRC_ID) + local nPrcIn = CreateProfilingProcessingCurve( nIn, nil, nGeoSurfId, nPrcLayerId) + local sInId = EgtGetInfo( nPrcIn, WIN_PRC_ID) EgtSetInfo( nPartId, WIN_PRC_PROFILE_IN, sInId) -- c) right @@ -5318,7 +5518,7 @@ local function CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLay local vProcRight = {} local vRefRight = {} for i = 1, #vRight do - local nCrvId = CreateProfilingProcessingCurve( vRight[i], nOut, nSurfGeo, nProcLayerId) + local nCrvId = CreateProfilingProcessingCurve( vRight[i], nOut, nGeoSurfId, nPrcLayerId) if nCrvId then table.insert( vProcRight, nCrvId) table.insert( vRefRight, vRight[i]) @@ -5329,7 +5529,7 @@ local function CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLay -- verifico se ci sono lavorazioni superflue TestProcessings( vProcRight, vRefRight, nOut, nIn) -- eventuale trim con out e in - local vPrcRight = EgtGetNameInGroup( nProcLayerId, WIN_RIGHT) + local vPrcRight = EgtGetNameInGroup( nPrcLayerId, WIN_RIGHT) TrimTangentProcessings( nPrcOut, vPrcRight[1], EgtEP( nPrcOut)) TrimTangentProcessings( vPrcRight[#vPrcRight], nPrcIn, EgtSP( nPrcIn)) @@ -5338,7 +5538,7 @@ local function CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLay local vProcLeft = {} local vRefLeft = {} for i = 1, #vLeft do - local nCrvId = CreateProfilingProcessingCurve( vLeft[i], nIn, nSurfGeo, nProcLayerId) + local nCrvId = CreateProfilingProcessingCurve( vLeft[i], nIn, nGeoSurfId, nPrcLayerId) if nCrvId then table.insert( vProcLeft, nCrvId) table.insert( vRefLeft, vLeft[i]) @@ -5346,145 +5546,544 @@ local function CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLay end vProcLeft, vRefLeft = ChainProfilingProcessingCurves( vProcLeft, vRefLeft) TestProcessings( vProcLeft, vRefLeft, nOut, nIn) - local vPrcLeft = EgtGetNameInGroup( nProcLayerId, WIN_LEFT) + local vPrcLeft = EgtGetNameInGroup( nPrcLayerId, WIN_LEFT) TrimTangentProcessings( nPrcIn, vPrcLeft[1], EgtEP( nPrcIn)) TrimTangentProcessings( vPrcLeft[#vPrcLeft], nPrcOut, EgtSP( nPrcOut)) end + +------------------------- CAMBIO PROFILO -------------------------- +--------------------------------------------------------------------- +-- calcola la curva di lavorazione in corrispondenza del centro utensile e la sua estensione +local function CalcToolCenterCurves( nOutlineId, nProfileId, nSemiProfileId, dOffsToolCenter, bOut, nGeoLayerId, nGeoSurfId, nPrcLayerId) + + -- partendo dalla curva del geo calcolo la curva di lavorazione base con gli allungamenti opportuni per garantire lavorazione completa lungo tutto il pezzo. + -- La curva del geo ha impostato come semiprofilo quello common, per i conti serve che abbia il semiprofilo della parte in analisi. + local nGeoCrv = EgtGetFirstNameInGroup( nGeoLayerId, EgtIf( bOut, WIN_GEO_OUT, WIN_GEO_IN)) + local nCopyGeo = EgtCopyGlob( nGeoCrv, nPrcLayerId) + EgtSetInfo( nCopyGeo, WIN_SEMI_PROFILE, nSemiProfileId) + local nToolCenterCrv = CreateProfilingProcessingCurve( nCopyGeo, nil, nGeoSurfId, nPrcLayerId) + if not bOut then + EgtInvertCurve( nToolCenterCrv) -- oriento come l'outline + end + -- porto sul centro utensile + EgtOffsetCurve( nToolCenterCrv, dOffsToolCenter) + + -- calcolo estensione a partire dall'outline + local bTangS = EgtGetInfo( nGeoCrv, WIN_TANG_START, 'b') + local bTangE = EgtGetInfo( nGeoCrv, WIN_TANG_END, 'b') + if not bOut then + -- se geo in le info di estensione sono riferite all'outline invertito + bTangS, bTangE = bTangE, bTangS + end + local nExtCrvTmp = CreateCurveOpenExtension( nOutlineId, nPrcLayerId, bTangS, bTangE) + local b3Profile = GetProfileLocalBox( nProfileId) + local nExtToolCenterCrv + if bOut then + nExtToolCenterCrv = EgtOffsetCurveAdv( nExtCrvTmp, b3Profile:getMax():getX() + dOffsToolCenter) + else + nExtToolCenterCrv = EgtOffsetCurveAdv( nExtCrvTmp, b3Profile:getMin():getX() + dOffsToolCenter) + end + + EgtErase( nExtCrvTmp) + EgtErase( nCopyGeo) + + return nToolCenterCrv, nExtToolCenterCrv +end + +--------------------------------------------------------------------- +-- funzione che modifica nCrvId tenendo solo la porzione che fa overlap con nRefId +local function KeepOverlapCurve( nCrvId, nRefId) + + local dPar1 = EgtCurveParamAtPoint( nRefId, EgtSP( nCrvId)) + local dPar2 = EgtCurveParamAtPoint( nRefId, EgtEP( nCrvId)) + local dParTrimS, dParTrimE + if not dPar1 then + dParTrimS = EgtCurveParamAtPoint( nCrvId, EgtSP( nRefId)) + end + if not dPar2 then + dParTrimE = EgtCurveParamAtPoint( nCrvId, EgtEP( nRefId)) + end + + if not dPar1 and not dPar2 and not dParTrimS and not dParTrimE then + -- le due curve non hanno porzione in comune quindi nCrvId va cancellata + EgtErase( nCrvId) + return false + else + -- se le due curve hanno una porzione comune verifico se è necessario trim di nCrvId + if dParTrimS and not dParTrimE then + EgtTrimCurveStartAtParam( nCrvId, dParTrimS) + elseif not dParTrimS and dParTrimE then + EgtTrimCurveEndAtParam( nCrvId, dParTrimE) + elseif dParTrimS and dParTrimE then + EgtTrimCurveStartEndAtParam( nCrvId, dParTrimS, dParTrimE) + end + end + return true +end + +--------------------------------------------------------------------- +local function CalcMixedSashTopProfilingProcessing( nOutlineId, vMixedCurves, bOut, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) + + local vPrc = {} + + -- calcolo la curva di lavorazione base e la sua estensione + local nSemiProfileSash = EgtGetFirstNameInGroup( nProfileId, WIN_SASH .. WIN_IN) or EgtGetFirstNameInGroup( nProfileId, WIN_SASH .. WIN_IN .. EgtIf( bOut, '1', '2')) + local dSashOverlap = EgtGetInfo( nProfileId, WIN_SASH_REF .. '1', 'd') + local dDiam = EgtGetInfo( nProfileId, WIN_SASH_DIAM .. '1', 'd') + local dOffsToolCenter = dSashOverlap - 0.5 * dDiam + if bOut then + dOffsToolCenter = - dOffsToolCenter + end + local nToolCenterCrv, nExtToolCenterCrv = CalcToolCenterCurves( nOutlineId, nProfileId, nSemiProfileSash, dOffsToolCenter, bOut, nGeoLayerId, nGeoSurfId, nPrcLayerId) + + -- recupero i parametri di interruzione della lavorazione sulla curva estesa ( la lavorazione si interrompe quando il tool è tangente al bisettore della curva di fresatura) + local vPar = { { dPar = 0}} + for i = 1, #vMixedCurves do + local nSplitId = EgtGetInfo( vMixedCurves[i], WIN_MIXED_SPLIT_REF, 'i') + local bStart = EgtGetInfo( vMixedCurves[i], WIN_MIXED_ONSTART, 'b') + local nBisectorOffsId = EgtGetInfo( vMixedCurves[i], WIN_MIXED_BISECTOR_REF, 'i') + local ptEnd = EgtIP( nBisectorOffsId, nExtToolCenterCrv, EgtIf( bStart, EgtSP( nSplitId), EgtEP( nSplitId))) + if ptEnd then + -- lo considero soltanto se il tool è tangente alla fresatura completa + local nCircle = EgtSurfFrDisk( nPrcLayerId, ptEnd, 0.5 * dDiam - 0.1) + if EgtSurfFrTestExternal( nCircle, vMixedCurves[i]) then + local dPar = EgtCurveParamAtPoint( nExtToolCenterCrv, ptEnd) + if dPar then + table.insert( vPar, { dPar = dPar, nId = vMixedCurves[i]}) + end + end + EgtErase( nCircle) + end + end + local _, dE = EgtCurveDomain( nExtToolCenterCrv) + table.insert( vPar, { dPar = dE}) + table.sort( vPar, function ( a, b) return a.dPar < b.dPar end) + + + local bSashFill + if #vPar == 2 then + -- caso eurisitico + local nSplitId = EgtGetInfo( vMixedCurves[1], WIN_MIXED_SPLIT_REF, 'i') + local bStart = EgtGetInfo( vMixedCurves[1], WIN_MIXED_ONSTART, 'b') + local ptRef = EgtIf( bStart, EgtSP( nSplitId), EgtEP( nSplitId)) + local dDistS = dist( ptRef, EgtSP( nOutlineId)) + local dDistE = dist( ptRef, EgtEP( nOutlineId)) + local bCurrSashFill = EgtGetInfo( vMixedCurves[1], WIN_MIXED_SASHFILL, 'b') + -- se la fresatura è più vicina allo start e fa passare da sash a fill oppure è vicina all'end e fa passare da fill a sash allora l'outline è tutto di fill ( bSashFill = false) + -- altrimenti è tutto di sash ( bSashFill = true) + if ( dDistS < dDistE and bCurrSashFill) or ( dDistS > dDistE and not bCurrSashFill) then + bSashFill = false + else + bSashFill = true + end + else + bSashFill = EgtGetInfo( vPar[2].nId, WIN_MIXED_SASHFILL, 'b') + end + if bOut then + bSashFill = not bSashFill + end + + -- se l'outline parte con sash devo tenere dal primo intervallo, altrimenti dal secondo + local nStart = EgtIf( bSashFill, 1, 2) + + -- ricavo le sottocurve della lavorazione + for i = nStart, #vPar - 1, 2 do + local nPrcCrv = EgtCopyParamRange( nExtToolCenterCrv, vPar[i].dPar, vPar[i+1].dPar, nPrcLayerId) + -- conservo soltanto la porzione di nPrcCrv che fa overlap con la lavorazione base, se esiste + local bValid = KeepOverlapCurve( nPrcCrv, nToolCenterCrv, dDiam) + if bValid then + table.insert( vPrc, nPrcCrv) + EgtSetName( nPrcCrv, WIN_SASH) + -- controffset per allinearla al bordo del pezzo + EgtOffsetCurve( nPrcCrv, - dOffsToolCenter) + end + end + + EgtErase( nExtToolCenterCrv) + EgtErase( nToolCenterCrv) + return vPrc +end + +--------------------------------------------------------------------- +local function CalcMixedSashBottomProfilingProcessing( nOutlineId, vMixedCurves, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) + + -- la parte sash ha due lavorazioni, una identica a quella fatta per il top e una specifica per il bottom. I due tool da utilizzare sono + -- presenti nelle info del semiprofilo e andranno divisi correttamente sulle due curve + + local nSemiProfile = EgtGetFirstNameInGroup( nProfileId, WIN_SASH .. WIN_IN) + + -- recupero le info specifiche dei due tool + local sToolName1 = EgtGetInfo( nSemiProfile, WIN_PRC_TOOL_NAME .. '_' .. '1') + local dOffsL1 = EgtGetInfo( nSemiProfile, WIN_PRC_OFFL .. '_' .. '1') + local dOffsR1 = EgtGetInfo( nSemiProfile, WIN_PRC_OFFR .. '_' .. '1') + local sToolName2 = EgtGetInfo( nSemiProfile, WIN_PRC_TOOL_NAME .. '_' .. '2') + local dOffsL2 = EgtGetInfo( nSemiProfile, WIN_PRC_OFFL .. '_' .. '2') + local dOffsR2 = EgtGetInfo( nSemiProfile, WIN_PRC_OFFR .. '_' .. '2') + + -- a) Tool 1 : la lavorazione è identica a quella del top + local vPrc1 = CalcMixedSashTopProfilingProcessing( nOutlineId, vMixedCurves, false, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) + for i = 1, #vPrc1 do + EgtSetInfo( vPrc1[i], WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) + EgtSetInfo( vPrc1[i], WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.LONGITUDINAL) + CopyInfo( vPrc1[i], nSemiProfile, WIN_PRC_PHASE) + CopyInfo( vPrc1[i], nSemiProfile, WIN_PRC_ID) + -- assegno le info del tool 1 + EgtSetInfo( vPrc1[i], WIN_PRC_NTOOLS, 1) + EgtSetInfo( vPrc1[i], WIN_PRC_TOOL_NAME .. '_' .. '1', sToolName1) + EgtSetInfo( vPrc1[i], WIN_PRC_OFFL .. '_' .. '1', dOffsL1) + EgtSetInfo( vPrc1[i], WIN_PRC_OFFR .. '_' .. '1', dOffsR1) + end + + -- b) Tool 2 + -- TODO : estendere se bottom non lineare ( possibile?) e split inclinati + -- calcolo la curva sul centro utensile + local b3FrameProfile = GetProfileLocalBox( nProfileId) + local dSashOverlap = EgtGetInfo( nProfileId, WIN_SASH_REF .. '3', 'd') + local dDiam = EgtGetInfo( nProfileId, WIN_SASH_DIAM .. '3', 'd') + local dOffsToolCenter = b3FrameProfile:getMin():getX() + dSashOverlap - 0.5 * dDiam + local nToolCenterCrv = EgtOffsetCurveAdv( nOutlineId, dOffsToolCenter) + + -- recupero i parametri di interruzione della lavorazione + local vPar = { { dPar = 0}} + for i = 1, #vMixedCurves do + local nSplitId = EgtGetInfo( vMixedCurves[i], WIN_MIXED_SPLIT_REF, 'i') + local nSplitProfile = GetOutlineProfileId( nSplitId) + local b3Profile = GetProfileLocalBox( nSplitProfile) + local bStart = EgtGetInfo( vMixedCurves[i], WIN_MIXED_ONSTART, 'b') + local nStart1 = EgtGetInfo( nSplitId, EgtIf( bStart, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '1', 'i') + local dOffs + local dFixedOverlap = EgtGetInfo( nSplitProfile, WIN_FIXED_REF, 'd') + if nStart1 == WIN_CHILDREN_TYPES.FILL then + dOffs = b3Profile:getMax():getX() - dFixedOverlap + else + dOffs = b3Profile:getMin():getX() + dFixedOverlap + end + local nSplitBorder = EgtOffsetCurveAdv( nSplitId, dOffs) + local ptEnd = EgtIP( nSplitBorder, nToolCenterCrv, ORIG()) + local dPar = EgtCurveParamAtPoint( nToolCenterCrv, ptEnd) + EgtErase( nSplitBorder) + table.insert( vPar, { dPar = dPar, nId = vMixedCurves[i]}) + end + + table.insert( vPar, { dPar = 1}) + table.sort( vPar, function ( a, b) return a.dPar < b.dPar end) + + local bSashFill = EgtGetInfo( vPar[2].nId, WIN_MIXED_SASHFILL, 'b') + local nStart = EgtIf( bSashFill, 1, 2) + + -- taglio in base ai parametri + for i = nStart, #vPar - 1, 2 do + local nPrcCrv = EgtCopyParamRange( nToolCenterCrv, vPar[i].dPar, vPar[i+1].dPar, nPrcLayerId) + EgtSetName( nPrcCrv, WIN_SASH) + -- controffset per allinearlo al bordo del pezzo + EgtOffsetCurve( nPrcCrv, b3FrameProfile:getMin():getX() - dOffsToolCenter) + + EgtSetInfo( nPrcCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) + EgtSetInfo( nPrcCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.LONGITUDINAL) + CopyInfo( nPrcCrv, nSemiProfile, WIN_PRC_PHASE) + CopyInfo( nPrcCrv, nSemiProfile, WIN_PRC_ID) + -- assegno le info del tool 2 + EgtSetInfo( nPrcCrv, WIN_PRC_NTOOLS, 1) + EgtSetInfo( nPrcCrv, WIN_PRC_TOOL_NAME .. '_' .. '1', sToolName2) + EgtSetInfo( nPrcCrv, WIN_PRC_OFFL .. '_' .. '1', dOffsL2) + EgtSetInfo( nPrcCrv, WIN_PRC_OFFR .. '_' .. '1', dOffsR2) + end + EgtErase( nToolCenterCrv) +end + +--------------------------------------------------------------------- +local function CalcMixedFillTopProfilingProcessing( nOutlineId, vMixedCurves, bOut, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) + + local vPrc = {} + + -- calcolo la curva di lavorazione base sul centro utensile e la sua estensione + local nSemiProfileFill = EgtGetFirstNameInGroup( nProfileId, WIN_FILL .. WIN_IN) or EgtGetFirstNameInGroup( nProfileId, WIN_FILL .. WIN_IN .. EgtIf( bOut, '1', '2')) + local dFillOverlap = EgtGetInfo( nProfileId, WIN_FIXED_REF, 'd') + local dDiam = EgtGetInfo( nProfileId, WIN_FILL_DIAM, 'd') + local dOffsToolCenter = dFillOverlap - 0.5 * dDiam + if bOut then + dOffsToolCenter = - dOffsToolCenter + end + local nToolCenterCrv, nExtToolCenterCrv = CalcToolCenterCurves( nOutlineId, nProfileId, nSemiProfileFill, dOffsToolCenter, bOut, nGeoLayerId, nGeoSurfId, nPrcLayerId) + + -- recupero i parametri di interruzione della lavorazione sulla curva estesa ( il tool deve fermarsi quando arriva al punto di intersezione tra la parte vetro fisso dello split + -- e la parte anta del telaio + local vPar = { { dPar = 0}} + for i = 1, #vMixedCurves do + + -- curva dello split in corrispondenza del vetro fisso + local nSplitId = EgtGetInfo( vMixedCurves[i], WIN_MIXED_SPLIT_REF, 'i') + local nSplitProfile = GetOutlineProfileId( nSplitId) + local b3Profile = GetProfileLocalBox( nSplitProfile) + local dFillOverlap = EgtGetInfo( nSplitProfile, WIN_FIXED_REF, 'd') + local bStart = EgtGetInfo( vMixedCurves[i], WIN_MIXED_ONSTART, 'b') + local nStart1 = EgtGetInfo( nSplitId, EgtIf( bStart, WIN_MIXED_START_CHILDREN, WIN_MIXED_END_CHILDREN) .. '1', 'i') + local dOffs + if nStart1 == WIN_CHILDREN_TYPES.FILL then + dOffs = b3Profile:getMax():getX() - dFillOverlap + else + dOffs = b3Profile:getMin():getX() + dFillOverlap + end + local nSplitCrvExt = CreateCurveOpenExtension( nSplitId, nPrcLayerId, false, false) + local nSplitCrv = EgtOffsetCurveAdv( nSplitCrvExt, dOffs) + + -- curva del pezzo in corrispondenza dell'ultimo "gradino" dell'anta ( SashRef3) + local dSash3Overlap = EgtGetInfo( nProfileId, WIN_SASH_REF .. '3', 'd') + if bOut then + dSash3Overlap = - dSash3Overlap + end + local nFrameCrv = EgtOffsetCurveAdv( nExtToolCenterCrv, - dOffsToolCenter + dSash3Overlap) + + -- calcolo il punto di intersezione + local ptRef = EgtIP( nSplitCrv, nFrameCrv, EgtIf( bStart, EgtSP( nSplitId), EgtEP( nSplitId))) + if ptRef then + -- lo considero solo se è interno al pezzo ( quindi la parte di vetro fisso dello split finisce veramente sul pezzo corrente) + local ptTest = EgtPoint( nPrcLayerId, ptRef) + if not EgtSurfFrTestExternal( nGeoSurfId, ptTest) then + -- calcolo il centro tool + local nTestTool = EgtCircle( nPrcLayerId, ptRef, 0.5 * dDiam) + local nId, nPntCnt = EgtCurveCurveInters( nTestTool, nExtToolCenterCrv, nPrcLayerId) + if nPntCnt == 2 then + + local dPar1 = EgtCurveParamAtPoint( nExtToolCenterCrv, EgtSP( nId)) + local dPar2 = EgtCurveParamAtPoint( nExtToolCenterCrv, EgtSP( nId + 1)) + local bSashFill = EgtGetInfo( vMixedCurves[i], WIN_MIXED_SASHFILL, 'b') + if bOut then + bSashFill = not bSashFill + end + -- se passo da anta a vetro devo conservare quello con parametro maggiore, altrimenti quello con parametro minore + local pt + if bSashFill then + if dPar1 > dPar2 - GEO.EPS_SMALL then + pt = EgtSP( nId) + else + pt = EgtSP( nId + 1) + end + else + if dPar1 < dPar2 + GEO.EPS_SMALL then + pt = EgtSP( nId) + else + pt = EgtSP( nId + 1) + end + end + + local dPar = EgtCurveParamAtPoint( nExtToolCenterCrv, pt) + if dPar then + table.insert( vPar, { dPar = dPar, nId = vMixedCurves[i]}) + end + end + for k = 1, nPntCnt do + EgtErase( nId + k - 1) + end + EgtErase( nTestTool) + end + EgtErase( ptTest) + end + EgtErase( nSplitCrv) + EgtErase( nFrameCrv) + EgtErase( nSplitCrvExt) + end + + local _, dE = EgtCurveDomain( nExtToolCenterCrv) + table.insert( vPar, { dPar = dE}) + table.sort( vPar, function ( a, b) return a.dPar < b.dPar end) + + + local bSashFill + if #vPar == 2 then + -- caso euristico + local nSplitId = EgtGetInfo( vMixedCurves[1], WIN_MIXED_SPLIT_REF, 'i') + local bStart = EgtGetInfo( vMixedCurves[1], WIN_MIXED_ONSTART, 'b') + local ptRef = EgtIf( bStart, EgtSP( nSplitId), EgtEP( nSplitId)) + local dDistS = dist( ptRef, EgtSP( nOutlineId)) + local dDistE = dist( ptRef, EgtEP( nOutlineId)) + local bCurrSashFill = EgtGetInfo( vMixedCurves[1], WIN_MIXED_SASHFILL, 'b') + -- se la fresatura è più vicina allo start e fa passare da sash a fill oppure è vicina all'end e fa passare da fill a sash allora l'outline è tutto di fill ( bSashFill = false) + -- altrimenti è tutto di sash ( bSashFill = true) + if ( dDistS < dDistE and bCurrSashFill) or ( dDistS > dDistE and not bCurrSashFill) then + bSashFill = false + else + bSashFill = true + end + else + bSashFill = EgtGetInfo( vPar[2].nId, WIN_MIXED_SASHFILL, 'b') + end + if bOut then + bSashFill = not bSashFill + end + + -- se l'outline parte con sash devo tenere dal secondo intervallo, altrimenti dal primo + local nStart = EgtIf( bSashFill, 2, 1) + + -- ricavo le sottocurve della lavorazione + for i = nStart, #vPar - 1, 2 do + local nPrcCrv = EgtCopyParamRange( nExtToolCenterCrv, vPar[i].dPar, vPar[i+1].dPar, nPrcLayerId) + -- conservo soltanto la porzione di nPrcCrv che fa overlap con la lavorazione base, se esiste + local bValid = KeepOverlapCurve( nPrcCrv, nToolCenterCrv, dDiam) + if bValid then + table.insert( vPrc, nPrcCrv) + EgtSetName( nPrcCrv, WIN_FILL) + -- controffset per allinearlo al bordo del pezzo + EgtOffsetCurve( nPrcCrv, - dOffsToolCenter) + end + end + + EgtErase( nExtToolCenterCrv) + EgtErase( nToolCenterCrv) + return vPrc +end + +--------------------------------------------------------------------- +-- funzione che calcola le lavorazioni legate alle sottoparti sash e fill e le fresature nel punto di separazione tra le sottoparti +local function CalcMixedProfilingProcessings( nOutlineId, vMixedCurves, vMixedMillings, bOut, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) + + local nPrcSide = EgtIf( bOut, WIN_PRC_SIDETYPE.OUT, WIN_PRC_SIDETYPE.IN) + if EgtGetName( nOutlineId) == WIN_BOTTOM then + -- la parte fill è fatta dalla parte comune + CalcMixedSashBottomProfilingProcessing( nOutlineId, vMixedCurves, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) + + else + -- lavorazione parte sash + local vSashPrc = CalcMixedSashTopProfilingProcessing( nOutlineId, vMixedCurves, bOut, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) + -- setto le info di lavorazione + local nSemiProfileSash = EgtGetFirstNameInGroup( nProfileId, WIN_SASH .. WIN_IN) or EgtGetFirstNameInGroup( nProfileId, WIN_SASH .. WIN_IN .. EgtIf( bOut, '1', '2')) + for i = 1, #vSashPrc do + GetProcessingInfoFromSemiProfile( vSashPrc[i], nSemiProfileSash) + EgtSetInfo( vSashPrc[i], WIN_PRC_SIDE, nPrcSide) + end + + -- lavorazione parte fill + local vFillPrc = CalcMixedFillTopProfilingProcessing( nOutlineId, vMixedCurves, bOut, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) + local nSemiProfileFill = EgtGetFirstNameInGroup( nProfileId, WIN_FILL .. WIN_IN) or EgtGetFirstNameInGroup( nProfileId, WIN_FILL .. WIN_IN .. EgtIf( bOut, '1', '2')) + for i = 1, #vFillPrc do + GetProcessingInfoFromSemiProfile( vFillPrc[i], nSemiProfileFill) + EgtSetInfo( vFillPrc[i], WIN_PRC_SIDE, nPrcSide) + end + end + + -- fresature + for i = 1, #vMixedMillings do + local nMilling = EgtCopyGlob( vMixedMillings[i], nPrcLayerId) + EgtSetInfo( nMilling, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) + EgtSetInfo( nMilling, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) + EgtSetInfo( nMilling, WIN_PRC_SIDE, nPrcSide) + end +end + --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profiling per un pezzo di telaio con cambio profilo -local function CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeoId) +local function CalcMixedFrameProfilingProcessings( nOutlineId, nPartId, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) -- a) lavorazioni profili -- per le lavorazioni dei profili out, left, right e in comune si usano le corrispondenti curve del geo - local nGeoArea = EgtGetLastInGroup( nGeoLayerId) - CreateProfilingProcessingFromGeo( nGeoLayerId, nGeoArea, nProcLayerId, nPartId) + CreateProfilingProcessingFromGeo( nPartId, nGeoLayerId, nGeoSurfId, nPrcLayerId) - -- b) lavorazioni per i sottotratti sash e fill - -- TO DO ( da capire bene soprattuto nei casi di cambio profilo che coinvolge pezzi distinti) + -- b) lavorazioni per i sottotratti sash e fill e relative fresature + local nMixedIntersLayerId = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_CURVES) + local vMixedCurves = EgtGetNameInGroup( nMixedIntersLayerId, WIN_MIXED_MILLING .. WIN_IN .. '1') + local vMixedMillings = EgtGetAllInGroup( nMixedIntersLayerId) + CalcMixedProfilingProcessings( nOutlineId, vMixedCurves, vMixedMillings, false, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) - -- c) fresature - local nMixedIntersGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_CURVES) - local vMixedInters = EgtGetAllInGroup( nMixedIntersGrp) - local dDepth1 = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1', 'd') - for i = 1, #vMixedInters do - local nMilling = EgtCopyGlob( vMixedInters[i], nProcLayerId) - -- sistemo spessore ( solo della fresatura 1, la seconda ha già profondità corretta) - if EgtEndsWith( EgtGetName( nMilling), '1') then - EgtModifyCurveThickness( nMilling, - dDepth1) - end - EgtSetInfo( nMilling, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) - EgtSetInfo( nMilling, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) - EgtSetInfo( nMilling, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN) - end end --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profiling nel caso di uno split coinvolto da cambio profilo -local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoLayerId, nMainProfileId) +local function CalcMixedSplitProfilingProcessings( nSplitId, nPartId, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) -- a) lavorazione dei profili - local nGeoArea = EgtGetLastInGroup( nGeoLayerId) - CreateProfilingProcessingFromGeo( nGeoLayerId, nGeoArea, nProcLayerId, EgtGetParent( nProcLayerId)) - - -- b) fresature - local nMixedIntersGrp = EgtGetFirstNameInGroup( EgtGetParent( nProcLayerId), WIN_MIXED_CURVES) + CreateProfilingProcessingFromGeo( nPartId, nGeoLayerId, nGeoSurfId, nPrcLayerId) - -- estremo start ( solo se presenta cambio profilo) - local nMillingLeft = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_LEFT .. '1') - if nMillingLeft then - local nPrcCrv = EgtCopyGlob( nMillingLeft, nProcLayerId) + -- b) lavorazioni legate al cambio profilo + local nPrfChange = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'i') + local nMixedIntersGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_CURVES) + + -- cambio profilo sul lato + if nPrfChange & WIN_PRF_CHANGE_TYPES.OUT > 0 then + local vMixedCrvs = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_OUT .. '1') + local vMixedMillings = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_OUT .. '*') + CalcMixedProfilingProcessings( nSplitId, vMixedCrvs, vMixedMillings, true, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) + end + + if nPrfChange & WIN_PRF_CHANGE_TYPES.IN > 0 then + local vMixedCrvs = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_IN .. '1') + local vMixedMillings = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_IN .. '*') + CalcMixedProfilingProcessings( nSplitId, vMixedCrvs, vMixedMillings, false, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) + end + + -- cambio profilo sull'estremo + local dDepth = EgtGetInfo( nProfileId, WIN_SASH_DEPTH .. '2', 'd') + if nPrfChange & WIN_PRF_CHANGE_TYPES.START > 0 then + local nMillingLeft = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_LEFT .. '1') + local nPrcCrv = EgtCopyGlob( nMillingLeft, nPrcLayerId) + EgtModifyCurveThickness( nPrcCrv, - dDepth) EgtSetInfo( nPrcCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) EgtSetInfo( nPrcCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) EgtSetInfo( nPrcCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.LEFT) end - - -- estremo end - local nMillingRight = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_RIGHT .. '1') - if nMillingRight then - local nPrcCrv = EgtCopyGlob( nMillingRight, nProcLayerId) + + if nPrfChange & WIN_PRF_CHANGE_TYPES.END > 0 then + local nMillingRight = EgtGetFirstNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_RIGHT .. '1') + local nPrcCrv = EgtCopyGlob( nMillingRight, nPrcLayerId) EgtInvertCurve( nPrcCrv) + EgtModifyCurveThickness( nPrcCrv, - dDepth) EgtSetInfo( nPrcCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) EgtSetInfo( nPrcCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) EgtSetInfo( nPrcCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.RIGHT) end - - -- lavorazioni legate ad altro split con cambio profilo che si innesta sullo split corrente - local dDepth1 = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1') - local vCrvsOut = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_OUT .. '*') - for i = 1, #vCrvsOut do - local nMilling = EgtCopyGlob( vCrvsOut[i], nProcLayerId) - if EgtEndsWith( EgtGetName( nMilling), '1') then - EgtModifyCurveThickness( nMilling, - dDepth1) - end - EgtSetInfo( nMilling, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) - EgtSetInfo( nMilling, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) - EgtSetInfo( nMilling, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.OUT) - end - - local vCrvsIn = EgtGetNameInGroup( nMixedIntersGrp, WIN_MIXED_MILLING .. WIN_IN .. '*') - for i = 1, #vCrvsIn do - local nMilling = EgtCopyGlob( vCrvsIn[i], nProcLayerId) - if EgtEndsWith( EgtGetName( nMilling), '1') then - EgtModifyCurveThickness( nMilling, - dDepth1) - end - EgtSetInfo( nMilling, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) - EgtSetInfo( nMilling, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) - EgtSetInfo( nMilling, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN) - end end +--------------------------------------------------------------------- --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profiling local function CalcProfilingProcessings( nPartId, nOutlineId) -- creo gruppo delle lavorazioni - local nProcLayerId = EgtGroup( nPartId) - EgtSetName( nProcLayerId, WIN_PRC) - EgtSetStatus( nProcLayerId, GDB_ST.OFF) + local nPrcLayerId = EgtGroup( nPartId) + EgtSetName( nPrcLayerId, WIN_PRC) + EgtSetStatus( nPrcLayerId, GDB_ST.OFF) -- recupero il geo e la superficie associata per limitare le lavorazioni local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) - local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) - local nSurfGeo = vGeoCrvs[#vGeoCrvs] + local nGeoSurfId = EgtGetLastInGroup( nGeoLayerId) -- recupero il gruppo dei profili local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) - local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) + local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) -- recupero le info di sovramateriale dal profilo - CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_IN, 0) - CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_OUT, 0) - CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_LEFT, 0) - CopyInfo( nPartId, nMainProfileId, WIN_PRC_OVERMAT_RIGHT, 0) + CopyInfo( nPartId, nProfileId, WIN_PRC_OVERMAT_IN, 0) + CopyInfo( nPartId, nProfileId, WIN_PRC_OVERMAT_OUT, 0) + CopyInfo( nPartId, nProfileId, WIN_PRC_OVERMAT_LEFT, 0) + CopyInfo( nPartId, nProfileId, WIN_PRC_OVERMAT_RIGHT, 0) -- calcolo lavorazioni dei profili local nPrfChange = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'i') or WIN_PRF_CHANGE_TYPES.NULL if nPrfChange > 0 then -- 1) cambio profilo ( su split o telaio) if EgtGetName( nOutlineId) == WIN_SPLIT then - CalcMixedSplitProfilingProcessings( nOutlineId, nProcLayerId, nGeoLayerId, nMainProfileId) + CalcMixedSplitProfilingProcessings( nOutlineId, nPartId, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) else - CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeo) + CalcMixedFrameProfilingProcessings( nOutlineId, nPartId, nProfileId, nGeoLayerId, nGeoSurfId, nPrcLayerId) end else -- 2) caso standard : costruisco le curve di lavorazione a partire da quelle del geo - CreateProfilingProcessingFromGeo( nGeoLayerId, nSurfGeo, nProcLayerId, nPartId) + CreateProfilingProcessingFromGeo( nPartId, nGeoLayerId, nGeoSurfId, nPrcLayerId) end -- calcolo eventuali lavorazioni per strip - local vStripDist = EgtGetInfo( nMainProfileId, WIN_STRIP_DIST, 'vi') or {} + local vStripDist = EgtGetInfo( nProfileId, WIN_STRIP_DIST, 'vi') or {} local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) local bTangStart = EgtGetInfo( nGeoIn, WIN_TANG_END, 'b') or false local bTangEnd = EgtGetInfo( nGeoIn, WIN_TANG_START, 'b') or false for i = 1, #vStripDist do - local nStripOutline = EgtCopyGlob( nOutlineId, nProcLayerId) + local nStripOutline = EgtCopyGlob( nOutlineId, nPrcLayerId) EgtOffsetCurve( nStripOutline, vStripDist[i]) -- estendo la curva per adattarla alla regione del geo basandomi sulle estensioni della curva in ( che dovrebbe essere quella più vicina) EgtSetInfo( nStripOutline, WIN_TANG_START, bTangStart) EgtSetInfo( nStripOutline, WIN_TANG_END, bTangEnd) - local nStripCut = CreateCurveExtension( nStripOutline, nProcLayerId) - local nRes, nCnt = EgtTrimCurveWithRegion( nStripCut, nSurfGeo, true, false) + local nStripCut = CreateCurveExtension( nStripOutline, nPrcLayerId) + local nRes, nCnt = EgtTrimCurveWithRegion( nStripCut, nGeoSurfId, true, false) -- se più di un tratto considero solo quello con sovrapposizione con la curva non estesa if nCnt > 1 and AreSamePointApprox( EgtSP( nRes), EgtEP( nRes + nCnt - 1)) then if EgtGetType( nRes) == GDB_TY.CRV_ARC then @@ -5617,7 +6216,7 @@ end --------------------------------------------------------------------- -- funzione che crea la guida per la superficie di trim, opportunamente estesa per avere booleane ben definite -local function CalcGuideExtension( nCrvId, nGeoId, nSemiProfile, nSurfTrimId, nLayerId) +local function CalcGuideExtension( nCrvId, nSemiProfile, nSurfTrimId, nLayerId) local nGrpTmp = EgtGroup( nLayerId) @@ -5625,6 +6224,10 @@ local function CalcGuideExtension( nCrvId, nGeoId, nSemiProfile, nSurfTrimId, nL local nExtCrvId = EgtCurveCompo( nGrpTmp, nCrvId, false) EgtAddCurveCompoLineTg( nExtCrvId, 10000, true) EgtAddCurveCompoLineTg( nExtCrvId, 10000, false) + -- parametri di trim ( come minimo sono quelli che mi riportano alla nCrvId di partenza) + local dParS, dParE = EgtCurveDomain( nExtCrvId) + dParS = 1 + dParE = dParE - 1 local nGuideId if not nSemiProfile then @@ -5639,17 +6242,13 @@ local function CalcGuideExtension( nCrvId, nGeoId, nSemiProfile, nSurfTrimId, nL local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frFrame = EgtFR( nFrameId, GDB_ID.ROOT) local b3SemiProfile = EgtGetBBoxRef( nSemiProfile, GDB_BB.STANDARD, frFrame) - - -- parametri di trim - local dParS = GEO.INFINITO - local dParE = -1 - + -- parte in local nInExtCrvId = EgtOffsetCurveAdv( nExtCrvId, b3SemiProfile:getMin():getX()) local nInId = GetReferenceCurve( nInExtCrvId, nCrvId, - b3SemiProfile:getMin():getX(), nSurfTrimId) if nInId then - dParS = EgtCurveParamAtPoint( nExtCrvId, EgtSP( nInId)) - dParE = EgtCurveParamAtPoint( nExtCrvId, EgtEP( nInId)) + dParS = min( dParS, EgtCurveParamAtPoint( nExtCrvId, EgtSP( nInId))) + dParE = max( dParE, EgtCurveParamAtPoint( nExtCrvId, EgtEP( nInId))) end -- parte out @@ -5700,7 +6299,7 @@ local function CreateTrimSurfs( vGeoIds, nLayerId, nMainGuideId, nMainProfileId) -- 1) minizinken if not nSemiProfileId then - nGuideId = CalcGuideExtension( vGeoIds[i], vGeoIds[i], nil, nSurfTrim, nLayerId) + nGuideId = CalcGuideExtension( vGeoIds[i], nil, nSurfTrim, nLayerId) EgtMove( nGuideId, Z_AX()) nTrimSurf = EgtSurfTmByExtrusion( nLayerId, nGuideId, - Z_AX() * 2 * b3Profile:getDimY(), WIN_SURF_APPROX) EgtInvertSurf( nTrimSurf) @@ -5715,20 +6314,10 @@ local function CreateTrimSurfs( vGeoIds, nLayerId, nMainGuideId, nMainProfileId) -- se la superficie di trim è già stata creata salvo associazione nella curva geo EgtSetInfo( vGeoIds[i], WIN_REF_SURF, tabPrcCrv[nPrcCrv]) else - -- nel caso di trim di split con cambio profilo non deve essere usato il semiprofilo common salvato nel geo, ma devo usare quello sash - local sSemiProfileName = EgtGetName( nSemiProfileId) - if sSemiProfileName == WIN_MIXED_COMMON .. WIN_IN then - nSemiProfileId = EgtGetFirstNameInGroup( EgtGetParent( nSemiProfileId), WIN_SASH .. WIN_CTRIN) - elseif sSemiProfileName == WIN_MIXED_COMMON .. WIN_IN .. '1' then - nSemiProfileId = EgtGetFirstNameInGroup( EgtGetParent( nSemiProfileId), WIN_SASH .. WIN_CTRIN .. '1') - elseif sSemiProfileName == WIN_MIXED_COMMON .. WIN_IN .. '2' then - nSemiProfileId = EgtGetFirstNameInGroup( EgtGetParent( nSemiProfileId), WIN_SASH .. WIN_CTRIN .. '2') - end - -- riposiziono la curva di lavorazione in corrispondenza dell'outline local dOffs = EgtGetInfo( vGeoIds[i], WIN_GEO_OFFS, 'd') local nOffsCrv = EgtOffsetCurveAdv( nPrcCrv, - dOffs) - nGuideId = CalcGuideExtension( nOffsCrv, vGeoIds[i], nSemiProfileId, nSurfTrim, nLayerId) + nGuideId = CalcGuideExtension( nOffsCrv, nSemiProfileId, nSurfTrim, nLayerId) EgtErase( nOffsCrv) local nRefOutline = EgtGetInfo( vGeoIds[i], WIN_REF_OUTLINE, 'i') if nRefOutline < 0 then @@ -5736,8 +6325,8 @@ local function CreateTrimSurfs( vGeoIds, nLayerId, nMainGuideId, nMainProfileId) end -- recupero il controprofilo da estrudere local sTrimProfileName = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. EgtGetName( nSemiProfileId) - -- calcolo la superficie di estrusione - nTrimSurf = CreateProfileSurf( nGuideId, EgtGetParent( nSemiProfileId), sTrimProfileName, b3Profile:getDimX(), nLayerId) + -- calcolo la superficie di estrusione ( piccola estensione per essere oltre il minimo indispensabile) + nTrimSurf = CreateProfileSurf( nGuideId, EgtGetParent( nSemiProfileId), sTrimProfileName, 2, nLayerId) tabPrcCrv[nPrcCrv] = nTrimSurf end end @@ -5759,44 +6348,13 @@ end --------------------------------------------------------------------- -- funzione che calcola la curva guida per il solido principale -local function CalcSolidGuide( nOutlineId, nSolidLayerId, nProfileId, nGeoLayerId) - - local nGuideId - local dExtraLinearLen = 400 - if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE then - -- se tratto lineare non ci sono problemi per l'estensione - nGuideId = EgtCopyGlob( nOutlineId, nSolidLayerId) - EgtExtendCurveStartByLen( nGuideId, dExtraLinearLen) - EgtExtendCurveEndByLen( nGuideId, dExtraLinearLen) +local function CalcSolidGuide( nOutlineId, nSolidLayerId, nGeoLayerId) - else - nGuideId = EgtCurveCompo( nSolidLayerId, nOutlineId, false) + local nGeoOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) + local bTangS = EgtGetInfo( nGeoOut, WIN_TANG_START, 'b') or false + local bTangE = EgtGetInfo( nGeoOut, WIN_TANG_END, 'b') or false - -- recupero il tipo di estensione - local nGeoOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) - local bTangS = EgtGetInfo( nGeoOut, WIN_TANG_START, 'b') - local bTangE = EgtGetInfo( nGeoOut, WIN_TANG_END, 'b') - - -- calcolo la lunghezza di estensione per l'arco in modo che la parte interna non si chiuda in una circonferenza - local dRad = EgtArcRadius( nOutlineId) - local dAng = EgtArcAngCenter( nOutlineId) * pi / 180 - local b3Profile = GetProfileLocalBox( nProfileId) - local dInnerRad = dRad - abs( b3Profile:getMin():getX()) - local dExtraLen = ( pi - 0.5 * dAng) * dInnerRad * dRad / dInnerRad - 2 - - if bTangS then - EgtAddCurveCompoLineTg( nGuideId, dExtraLinearLen, false) - else - EgtExtendCurveStartByLen( nGuideId, dExtraLen) - end - - if bTangE then - EgtAddCurveCompoLineTg( nGuideId, dExtraLinearLen, true) - else - EgtExtendCurveEndByLen( nGuideId, dExtraLen) - end - end - + local nGuideId = CreateCurveOpenExtension( nOutlineId, nSolidLayerId, bTangS, bTangE) EgtSetName( nGuideId, WIN_MAINGUIDE) EgtSetStatus( nGuideId, GDB_ST.OFF) @@ -5805,20 +6363,39 @@ end --------------------------------------------------------------------- -- funzione che crea la superficie di taglio corrispondente alle fresature del cambio profilo che separano le parti sash e fill -local function CalcMixedCurveTrimSurf( vMixedCurves, nSolidLayerId, dExtraLen) +local function CalcMixedCurveTrimSurf( vMixedCurves, bOut, nSolidLayerId, dExtraLen) local vStmInters = {} for i = 1, #vMixedCurves do local nSplitId = EgtGetInfo( vMixedCurves[i], WIN_MIXED_SPLIT_REF, 'i') - local vtDir = EgtSV( nSplitId) - local bFillOnSplitRight = EgtGetInfo( vMixedCurves[i], WIN_FILL_ON_SPLIT_RIGHT, 'b') - if bFillOnSplitRight then - vtDir = - vtDir - end + local bSashFill = EgtGetInfo( vMixedCurves[i], WIN_MIXED_SASHFILL, 'b') + local bOnStart = EgtGetInfo( vMixedCurves[i], WIN_MIXED_ONSTART, 'b') local nCrvTrim = EgtCopyGlob( vMixedCurves[i], nSolidLayerId) - EgtAddCurveCompoLine( nCrvTrim, EgtSP( nCrvTrim) + 3 * dExtraLen * vtDir, false) - EgtAddCurveCompoLine( nCrvTrim, EgtEP( nCrvTrim) - 3 * dExtraLen * vtDir) + + -- ricavo la direzione legata allo split + local vtSplit = EgtSV( nSplitId) + if not bOnStart then + vtSplit = - vtSplit + end + + -- se sashfill sullo start serve la direzione ricavata dall'outline e sull'end quella ricavata dallo split + -- se no sashfill sullo start serve la direzione ricavata dallo split e sull'end quella ricavata dall'outline + local nGuide = EgtGetFirstNameInGroup( nSolidLayerId, WIN_MAINGUIDE) + if bSashFill then + local _, _, dParMinDist = EgtPointCurveDist( EgtSP( nCrvTrim), nGuide) + local vtStart = EgtUV( nGuide, dParMinDist, -1) + vtStart:rotate( Z_AX(), EgtIf( bOut, 90, -90)) + EgtAddCurveCompoLine( nCrvTrim, EgtSP( nCrvTrim) + 3 * dExtraLen * vtStart, false) + EgtAddCurveCompoLine( nCrvTrim, EgtEP( nCrvTrim) + 3 * dExtraLen * vtSplit, true) + else + local _, _, dParMinDist = EgtPointCurveDist( EgtEP( nCrvTrim), nGuide) + local vtEnd = EgtUV( nGuide, dParMinDist, -1) + vtEnd:rotate( Z_AX(), EgtIf( bOut, 90, -90)) + EgtAddCurveCompoLine( nCrvTrim, EgtEP( nCrvTrim) + 3 * dExtraLen * vtEnd, true) + EgtAddCurveCompoLine( nCrvTrim, EgtSP( nCrvTrim) + 3 * dExtraLen * vtSplit, false) + end + EgtMove( nCrvTrim, Z_AX()) EgtSetStatus( nCrvTrim, GDB_ST.OFF) vStmInters[i] = EgtSurfTmByExtrusion( nSolidLayerId, nCrvTrim, - 2 * dExtraLen * Z_AX()) @@ -5834,7 +6411,7 @@ end local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId, dGeoWidth) -- a) solido principale - local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId) + local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nGeoLayerId) EgtSetName( nGuideId, WIN_MAINGUIDE) EgtSetStatus( nGuideId, GDB_ST.OFF) -- creo i solidi corrispondenti alla parte sash e alla parte fill @@ -5846,7 +6423,7 @@ local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nMainProfileId, n -- calcolo le superfici di taglio corrispondenti alle fresature del cambio profilo che separano la parte sash e fill local nMixedIntersectionsGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_CURVES) local vIntersections = EgtGetNameInGroup( nMixedIntersectionsGrp, WIN_MIXED_MILLING .. WIN_IN .. '1') - local nStmTrim = CalcMixedCurveTrimSurf( vIntersections, nSolidLayerId, dGeoWidth) + local nStmTrim = CalcMixedCurveTrimSurf( vIntersections, false, nSolidLayerId, dGeoWidth) -- taglio le parti sash e fill e le riunisco in una sola superficie EgtSurfTmIntersect( nMainFill, nStmTrim) @@ -5869,7 +6446,7 @@ local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nMainProfileId, n EgtSurfTmIntersect( nMainSolid, vTrimStart[i]) end - -- c) trim end + -- c) trim end local vNextGeoIds = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) local vTrimEnd = CreateTrimSurfs( vNextGeoIds, nSolidLayerId, nGuideId, nMainProfileId) for i = 1, #vTrimEnd do @@ -5902,7 +6479,8 @@ local function CreateMixedSplitTrimSurfs( vGeoCrvs, bStart, nSolidLayerId, nSpli EgtAddCurveCompoLine( nGuide, EgtSP( nGuide) + 2 * dGeoWidth * vtDir, false) EgtCloseCurveCompo( nGuide) EgtMove( nGuide, 0.01 * Z_AX()) - local nMillStm = EgtSurfTmByRegionExtrusion( nSolidLayerId, nGuide, ( EgtCurveThickness( nGuide) - 2) * Z_AX()) + local dDepth = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '2', 'd') + local nMillStm = EgtSurfTmByRegionExtrusion( nSolidLayerId, nGuide, - ( dDepth + 0.5) * Z_AX()) -- lo sottraggo alle superfici di trim for i = 1, #vTrimSurfs do @@ -5938,7 +6516,7 @@ end local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId, dGeoWidth) -- a) solido principale - local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId) + local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nGeoLayerId) -- creo un solido per ogni lato dello split local vSolids = {} for i = 1, 2 do @@ -5959,7 +6537,7 @@ local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nMainProfileId, n -- calcolo le superfici di taglio corrispondenti alle fresature del cambio profilo che separano la parte sash e fill local nMixedIntersectionsGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_CURVES) local vIntersections = EgtGetNameInGroup( nMixedIntersectionsGrp, WIN_MIXED_MILLING .. EgtIf( i == 1, WIN_OUT, WIN_IN) .. '1') - local nStmTrim = CalcMixedCurveTrimSurf( vIntersections, nSolidLayerId, dGeoWidth) + local nStmTrim = CalcMixedCurveTrimSurf( vIntersections, i == 1, nSolidLayerId, dGeoWidth) -- costruisco il solido combinando opportunamente le parti sash e fill EgtSurfTmIntersect( nFillSolid, nStmTrim) @@ -6032,7 +6610,7 @@ local function CalcSolid( nPartId, nOutlineId) end -- a) creo il solido di estrusione principale - local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nMainProfileId, nGeoLayerId) + local nGuideId = CalcSolidGuide( nOutlineId, nSolidLayerId, nGeoLayerId) local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION local nMainExtrusionId = CreateProfileSurf( nGuideId, nMainProfileId, sSection, 0, nSolidLayerId) EgtSetName( nMainExtrusionId, WIN_SRF_MAIN) @@ -6314,7 +6892,7 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo -- superficie test per il posizionamento dei dowels : è la superficie in del pezzo full local nTestSurf if not s_bCalcSolid or s_bSimplSolid then - local sCtrIn = WIN_OFST .. GetProfileCtrIn( nOrigOutlineId, nPrevOutlineId, nProfileId, false) -- controprofilo in del pezzo corrente + local sCtrIn = WIN_OFST .. GetProfileCtrIn( nOrigOutlineId, nPrevOutlineId, false) -- controprofilo in del pezzo corrente nTestSurf = CreateProfileSurf( nOrigOutlineId, nProfileId, sCtrIn, 100, nLayerId) else -- è la superficie che viene utilizzata per trimmare l'end del pezzo prev @@ -6375,7 +6953,7 @@ local function CalcDowels( nOrigOutlineId, nOrigPrevOutlineId, bSashOrFrame, nBo -- è il controprofilo in del pezzo full quindi è la stessa superficie che viene utilizzata per trimmare lo start del pezzo corrente local nTestSurf if not s_bCalcSolid or s_bSimplSolid then - local sCtrIn = WIN_OFST .. GetProfileCtrIn( nOrigPrevOutlineId, nOutlineId, nPrevProfileId, true) -- controprofilo del pezzo full + local sCtrIn = WIN_OFST .. GetProfileCtrIn( nOrigPrevOutlineId, nOutlineId, true) -- controprofilo del pezzo full nTestSurf = CreateProfileSurf( nOrigPrevOutlineId, nPrevProfileId, sCtrIn, 100, nLayerId) else local nOrigSurf = EgtGetInfo( nCurrLeft, WIN_REF_SURF, 'i') @@ -6447,7 +7025,7 @@ local function CalcSplitDowels( nSplitId, bStartOrEnd) local vAuxSurfs = {} if not s_bCalcSolid or s_bSimplSolid then -- simulo la guida per il calcolo del solido - local nGuideId = CalcSolidGuide( nSplitId, nSplitLayerId, nSplitProfile, nSplitGeo) + local nGuideId = CalcSolidGuide( nSplitId, nSplitLayerId, nSplitGeo) if EgtGetInfo( nSplitId, WIN_SPLITTYPE, 'i') == WIN_SPLITTYPES.MIXED then vAuxSurfs = CreateMixedSplitTrimSurfs( vGeoCrvs, bStartOrEnd, nSplitLayerId, nSplitId, nGuideId, nSplitProfile, 100) else