-- -- EEEEEEEEEE GGGGGG TTTTTTTTTTTTTT -- EEEEEEEEEE GGGGGGGGGG TTTTTTTTTTTTTT -- EEEE GGGG GGGG TTTT -- EEEE GGGG TTTT -- EEEEEEE GGGG GGGGGGG TTTT -- EEEEEEE GGGG GGGGGGG TTTT -- EEEE GGGG GGGG TTTT -- EEEE GGGG GGGG TTTT -- EEEEEEEEEE GGGGGGGGGG TTTT -- EEEEEEEEEE GGGGGG TTTT -- -- by Egalware s.r.l. -- Window project software by Egalware s.r.l. 2023/05/02 -- Tabella per definizione modulo local WinCalculate = {} -- Include require( 'EgtBase') require( 'WinConst') local s_dDowelTol = 1 local s_bCalcSolid = false function WinCalculate.GetCalcSolid() return s_bCalcSolid end function WinCalculate.SetCalcSolid( bValue) s_bCalcSolid = bValue end local s_bSimplSolid = false function WinCalculate.SetSimplifiedSolid( bValue) s_bSimplSolid = bValue end --------------------------------------------------------------------- -- funzione che copia la info di chiave sInfo da nSou a nDest local function CopyInfo( nDest, nSou, sInfo, Default) local sVal = EgtGetInfo( nSou, sInfo) or Default EgtSetInfo( nDest, sInfo, sVal) end --------------------------------------------------------------------- -- funzione che trova punto di intersezione fra due curve eventualmente estendendole local function FindIntersectionPoint( nCrv1, nCrv2, ptRef) local ptInt = EgtIP( nCrv1, nCrv2, ptRef) if not ptInt then -- se entrambe linee if EgtGetType( nCrv1) == GDB_TY.CRV_LINE and EgtGetType( nCrv2) == GDB_TY.CRV_LINE then EgtExtendCurveStartByLen( nCrv1, 10000) EgtExtendCurveEndByLen( nCrv1, 10000) EgtExtendCurveStartByLen( nCrv2, 10000) EgtExtendCurveEndByLen( nCrv2, 10000) ptInt = EgtIP( nCrv1, nCrv2, ptRef) -- se entrambi archi elseif EgtGetType( nCrv1) == GDB_TY.CRV_ARC and EgtGetType( nCrv2) == GDB_TY.CRV_ARC then -- trovo intersezione tra le due circonferenze local nCircle1 = EgtCircle( GDB_ID.ROOT, EgtCP( nCrv1), EgtArcRadius( nCrv1)) local nCircle2 = EgtCircle( GDB_ID.ROOT, EgtCP( nCrv2), EgtArcRadius( nCrv2)) ptInt = EgtIP( nCircle1, nCircle2, ptRef) EgtModifyCurveStartPoint( nCrv1, ptInt) EgtModifyCurveEndPoint( nCrv2, ptInt) EgtErase( nCircle1) EgtErase( nCircle2) -- se arco e linea else local nLine = EgtIf( EgtGetType( nCrv1) == GDB_TY.CRV_LINE, nCrv1, nCrv2) local nArc = EgtIf( nLine == nCrv1, nCrv2, nCrv1) -- tento di trovare intersezione prolungando la linea EgtExtendCurveStartByLen( nLine, 10000) EgtExtendCurveEndByLen( nLine, 10000) ptInt = EgtIP( nArc, nLine, ptRef) if not ptInt then -- creo circonferenza corrispondente all'arco local nCircle = EgtCircle( GDB_ID.ROOT, EgtCP( nArc), EgtArcRadius( nArc)) -- trovo l'intersezione tra retta e circonferenza local ptDist = EgtIf( nArc == nCrv2, EgtEP( nArc), EgtSP( nArc)) local _, ptRef = EgtPointCurveDist( ptDist, nLine) ptInt = EgtIP( nCircle, nLine, ptRef) EgtErase( nCircle) -- allungo l'arco per arrivare al punto di intersezione if nArc == nCrv2 then EgtModifyCurveEndPoint( nArc, ptInt) else EgtModifyCurveStartPoint( nArc, ptInt) end end end end return ptInt end --------------------------------------------------------------------- -- funzione che data una lista di curve ordinate che creano una curva chiusa, -- ne estende/taglia i contorni per ottenere una curva chiusa continua local function TrimAndOrientOrderedCurves( vCrvs, bOrient) local IntersCurveList = {} local LastCurveInters -- ciclo sulle curve per ottenere lista intersezioni for i = 1, #vCrvs do -- recupero la precedente local nPrevIndex = EgtIf( i == 1, #vCrvs, i - 1) -- calcolo intersezione local ptInters = FindIntersectionPoint( vCrvs[i], vCrvs[ nPrevIndex], EgtSP( vCrvs[i])) if LastCurveInters then LastCurveInters.EndInters = Point3d( ptInters) -- se il punto di intersezione è lo stesso trovato nell'iterazione precedente cerco una seconda -- intersezione tra le due curve if AreSamePointApprox( ptInters, LastCurveInters.StartInters) then ptInters = FindIntersectionPoint( vCrvs[i], vCrvs[ nPrevIndex], EgtEP( vCrvs[i])) LastCurveInters.EndInters = Point3d( ptInters) end end local NewCurveInters = { CurveId = vCrvs[i], StartInters = Point3d( ptInters)} table.insert( IntersCurveList, NewCurveInters) LastCurveInters = NewCurveInters end IntersCurveList[#IntersCurveList].EndInters = IntersCurveList[1].StartInters -- ciclo per tagliare ed orientare for nIntersCurveIndex = 1, #IntersCurveList do local CurveInters = IntersCurveList[nIntersCurveIndex] local dStartParam = EgtCurveParamAtPoint( CurveInters.CurveId, CurveInters.StartInters, 100 * GEO.EPS_SMALL) local dEndParam = EgtCurveParamAtPoint( CurveInters.CurveId, CurveInters.EndInters, 100 * GEO.EPS_SMALL) EgtTrimCurveStartEndAtParam( CurveInters.CurveId, min( dStartParam, dEndParam), max( dStartParam, dEndParam)) if bOrient and dStartParam > dEndParam then EgtInvertCurve( CurveInters.CurveId) end end end --------------------------------------------------------------------- local function TrimSplitWithOutline( nSplitId) -- estendo agli estremi ( TO DO : gestire caso di split non lineare) EgtExtendCurveStartByLen( nSplitId, 50) EgtExtendCurveEndByLen( nSplitId, 50) -- lo taglio con outline local nStartIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'i') local nOutlineId = EgtGetInfo( nStartIntersId, WIN_COPY, 'i') local ptStartInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId)) local dStartInters = EgtCurveParamAtPoint( nSplitId, ptStartInters) EgtTrimCurveStartAtParam( nSplitId, dStartInters) local nEndIntersId = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'i') nOutlineId = EgtGetInfo( nEndIntersId, WIN_COPY, 'i') local ptEndInters = EgtIP( nSplitId, nOutlineId, EgtSP( nSplitId)) local dEndInters = EgtCurveParamAtPoint( nSplitId, ptEndInters) EgtTrimCurveEndAtParam( nSplitId, dEndInters) end --------------------------------------------------------------------- -- funzione che data una curva di outline restituisce l'id del suo profilo local function GetOutlineProfileId( nOutlineId, bUseBottomRail) -- ciclo fino a trovare il primo parent che abbia un AreaType definito ( frame o sash) local nParentId = EgtGetParent( nOutlineId) local nAreaType = WIN_AREATYPES.NULL while nParentId and ( nAreaType == WIN_AREATYPES.SPLIT or nAreaType == WIN_AREATYPES.NULL) do nParentId = EgtGetParent( nParentId) nAreaType = EgtGetInfo( nParentId or GDB_ID.NULL, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL end -- recupero il gruppo contenente il profilo local nProfilesGrpId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) local nLayerId if nAreaType == WIN_AREATYPES.FRAME then nLayerId = EgtGetFirstNameInGroup( nProfilesGrpId, WIN_FRAME) elseif nAreaType == WIN_AREATYPES.SASH then nLayerId = EgtGetFirstNameInGroup( nProfilesGrpId, WIN_SASH) end -- recupero il nome del profilo local sProfileName = EgtGetInfo( nOutlineId, WIN_PROFILETYPE) -- verifico se bottom rail if bUseBottomRail then local nOutlineLay = EgtGetFirstNameInGroup( nParentId, WIN_AREAOUTLINE) local bBottomRail = EgtGetInfo( nOutlineLay, WIN_BOTTOMRAIL, 'b') or false local sOutlineName = EgtGetName( nOutlineId) if sOutlineName == WIN_BOTTOM and bBottomRail then -- allora imposto profilo BottomRail sProfileName = WIN_RAIL_BOTTOM end end -- recupero il profilo return EgtGetFirstNameInGroup( nLayerId, sProfileName) end --------------------------------------------------------------------- -- funzione che recupera il pezzo associato ad un outline local function FindAssociatedPart( nOutlineId) local nPartId = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i') or EgtGetInfo( nOutlineId, WIN_REF_PART, 'i') if not nPartId then -- cerco la prima curva da cui deriva che ha un pezzo associato local nBaseOutline = EgtGetInfo( nOutlineId, WIN_COPY, 'i') while not nPartId do -- recupero il base outline da cui deriva nBaseOutline = EgtGetInfo( nBaseOutline, WIN_SOU, 'i') -- verifico se ha un profilo associato ( e quindi un pezzo) local sProfileType = EgtGetInfo( nBaseOutline, WIN_PROFILETYPE) if sProfileType then -- recupero l'outline associato local nCrvId = EgtGetInfo( nBaseOutline, WIN_COPY, 'i') nPartId = EgtGetInfo( nCrvId, WIN_REF_BOTTOMRAIL_PART, 'i') or EgtGetInfo( nCrvId, WIN_REF_PART, 'i') end end end return nPartId end --------------------------------------------------------------------- -- funzione che calcola il box di un profilo ( guardando la sua curva Ref) rispetto al suo frame local function GetProfileLocalBox( nProfileId) -- recupero il frame del profilo local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frFrame = EgtFR( nFrameId, GDB_ID.ROOT) -- recupero il Ref del profilo e ne calcolo il box local nRefId = EgtGetFirstNameInGroup( nProfileId, WIN_REF) local b3Box = EgtGetBBoxRef( nRefId, GDB_BB.STANDARD, frFrame, GDB_RT.GLOB) return b3Box end ---------------------------------------------------------------------------------- ----------------------------- CALCOLO DEI PROFILI ------------------------------ ---------------------------------------------------------------------------------- -- funzione che restituisce il primo tipo di area definito tra le sottoaree che si generano da nAreaId local function GetAreaChildrenType( nAreaId) local vStack = EgtGetNameInGroup( nAreaId, WIN_AREA .. '*') or {} local i = 1 while vStack[i] do local nType = EgtGetInfo( vStack[i], WIN_AREATYPE, 'i') -- appena trovo un tipo definito esco if nType == WIN_AREATYPES.FILL then return WIN_CHILDREN_TYPES.FILL elseif nType == WIN_AREATYPES.SASH then return WIN_CHILDREN_TYPES.SASH else -- altrimenti analizzo le sottoaree local vSubAreas = EgtGetNameInGroup( vStack[i], WIN_AREA .. '*') or {} vStack = EgtJoinTables( vStack, vSubAreas) end i = i + 1 end -- se non trovo un tipo definito return WIN_CHILDREN_TYPES.NULL end --------------------------------------------------------------------- local function GetClosestAreaChildrenType( nAreaId) local nChildrenType = WIN_CHILDREN_TYPES.NULL local nType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') while nChildrenType == WIN_CHILDREN_TYPES.NULL and nType ~= WIN_AREATYPES.FRAME do nAreaId = EgtGetParent( nAreaId) nType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') nChildrenType = GetAreaChildrenType( nAreaId) end return nChildrenType end --------------------------------------------------------------------- -- funzione che verifica la tipologia delle curve figlie di una curva local function GetChildrenType( nCrvId) local vStack = EgtGetInfo( nCrvId, WIN_CHILD, 'vi') or {} local i = 1 local vFillChildren = {} local vSashChildren = {} while vStack[i] do -- verifico se la sua area è di tipo sash o fill local nAreaId = EgtGetParent( EgtGetParent( vStack[i])) local nType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') if nType == WIN_AREATYPES.FILL then table.insert( vFillChildren, vStack[i]) elseif nType == WIN_AREATYPES.SASH then table.insert( vSashChildren, vStack[i]) else -- recupero i suoi figli local vChildren = EgtGetInfo( vStack[i], WIN_CHILD, 'vi') or {} if #vChildren == 0 then -- se non ha figli, per non creare problemi nel caso di cambio profilo ( in cui è necessario conoscere la struttura completa), -- assegno come tipologia quella dell'area più "vicina" nella struttura delle aree local nCurrType = GetClosestAreaChildrenType( nAreaId) if nCurrType == WIN_CHILDREN_TYPES.FILL then table.insert( vFillChildren, vStack[i]) elseif nCurrType == WIN_CHILDREN_TYPES.SASH then table.insert( vSashChildren, vStack[i]) end end -- aggiungo i suoi figli tra gli elementi da analizzare vStack = EgtJoinTables( vStack, vChildren) end -- aggiorno il contatore i = i + 1 end -- salvo i figli individuati come info della curva EgtSetInfo( nCrvId, WIN_SASH_CHILDREN, vSashChildren) EgtSetInfo( nCrvId, WIN_FILL_CHILDREN, vFillChildren) if #vFillChildren > 0 and #vSashChildren > 0 then return WIN_CHILDREN_TYPES.MIXED -- cambio profilo elseif #vFillChildren > 0 then return WIN_CHILDREN_TYPES.FILL elseif #vSashChildren > 0 then return WIN_CHILDREN_TYPES.SASH else return WIN_CHILDREN_TYPES.NULL end end --------------------------------------------------------------------- -- funzione che identifica il tipo di split ( null, mullion, french, mixed) local function GetSplitType( nSplitLayerId) local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i') -- se non ha split specifico impostato verifico se ha sash prima o dopo per capire se è di tipo mullion if not nSplitType or nSplitType == WIN_SPLITTYPES.NULL then local nParentAreaId = EgtGetParent( nSplitLayerId) local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL while nParentAreaId and nParentAreaType ~= WIN_AREATYPES.SASH do nParentAreaId = EgtGetParent( nParentAreaId) nParentAreaType = EgtGetInfo( nParentAreaId or GDB_ID.NULL, WIN_AREATYPE, 'i') or WIN_AREATYPES.NULL end -- se dentro anta è di tipo null, se non è dentro anta devo verificare le tipologie dei figli if not nParentAreaId or nParentAreaType ~= WIN_AREATYPES.SASH then local nSplitId = EgtGetFirstInGroup( nSplitLayerId) local nChildrenType = GetChildrenType( nSplitId) if nChildrenType == WIN_CHILDREN_TYPES.MIXED then nSplitType = WIN_SPLITTYPES.MIXED elseif nChildrenType == WIN_CHILDREN_TYPES.SASH or nChildrenType == WIN_CHILDREN_TYPES.NULL then nSplitType = WIN_SPLITTYPES.MULLION end end end if not nSplitType then nSplitType = WIN_SPLITTYPES.NULL end EgtSetInfo( nSplitLayerId, WIN_SPLITTYPE, nSplitType) return nSplitType end --------------------------------------------------------------------- -- funzione che imposta i tipi di profilo per gli split local function CalcSplitProfileType( nSplitLayerId, nAreaId) local nSplitId = EgtGetFirstInGroup( nSplitLayerId) -- verifico il tipo di split local nSplitType = GetSplitType( nSplitLayerId) if nSplitType == WIN_SPLITTYPES.MULLION then -- verifico direzione per dare nome local vtMedia = ( ( EgtEV( nSplitId) - EgtSV( nSplitId)) / 2) if not vtMedia:normalize() then vtMedia = EgtSV( nSplitId) end if abs( vtMedia:getX()) > abs( vtMedia:getY()) then EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_SASH_HORIZONTAL) else EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_SASH_VERTICAL) end elseif nSplitType == WIN_SPLITTYPES.NULL then -- verifico se interno ad anta o a frame local nParentAreaId = nAreaId local nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') while nParentAreaType ~= WIN_AREATYPES.FRAME and nParentAreaType ~= WIN_AREATYPES.SASH do nParentAreaId = EgtGetParent( nParentAreaId) nParentAreaType = EgtGetInfo( nParentAreaId, WIN_AREATYPE, 'i') end -- assegno tipo di profilo allo split if nParentAreaType == WIN_AREATYPES.SASH then EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_SASH_SPLIT) else EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_FRAME_SPLIT) end elseif nSplitType == WIN_SPLITTYPES.MIXED then EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_MIXED_SPLIT) EgtSetInfo( nSplitId, WIN_PRF_CHANGE, true) -- verifico se l'orientamento dello split è coerente con il cambio profilo ( vetro fisso a destra e anta a sinistra) : -- recupero il lato da cui si trova il figlio di tipo anta local nSashChild = EgtGetInfo( nSplitId, WIN_SASH_CHILDREN, 'i') local nRefCrv = EgtGetNext( nSashChild) or EgtGetPrev( nSashChild) local _, _, nSide = EgtPointCurveDistSide( EgtMP( nRefCrv), nSplitId, Z_AX()) -- se si trova a destra, lo split va invertito if nSide == 1 then EgtInvertCurve( nSplitId) -- scambio le info di intersezione local vStartInters = EgtGetInfo( nSplitId, WIN_SPLIT_STARTINTERS, 'vi') local vEndInters = EgtGetInfo( nSplitId, WIN_SPLIT_ENDINTERS, 'vi') EgtSetInfo( nSplitId, WIN_SPLIT_STARTINTERS, vEndInters) EgtSetInfo( nSplitId, WIN_SPLIT_ENDINTERS, vStartInters) end end -- se split di tipo french non ha profilo assegnato perchè non ha un pezzo associato end --------------------------------------------------------------------- local function FindAdjacentSashType( nSplitId, nSouId) -- recupero l'altro child dello split local vSplitChildren = EgtGetInfo( nSplitId, WIN_CHILD, 'vi') local vChildren = EgtIf( vSplitChildren[1] == nSouId, {vSplitChildren[2]}, {vSplitChildren[1]}) -- cerco il suo primo figlio di tipo sash local nAreaType local nArea repeat vChildren = EgtGetInfo( vChildren[1], WIN_CHILD, 'vi') if vChildren then nArea = EgtGetParent( EgtGetParent( vChildren[1])) nAreaType = EgtGetInfo( nArea or GDB_ID.NULL, WIN_AREATYPE, 'i') end until not vChildren or nAreaType == WIN_AREATYPES.SASH -- recupero il sash type local nSashType = EgtGetInfo( nArea or GDB_ID.NULL, WIN_SASHTYPE, 'i') return nSashType end --------------------------------------------------------------------- -- funzione che imposta i tipi di profilo in base al tipo di pezzi local function CalcProfileType( nAreaId) local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') -- FRAME if nAreaType == WIN_AREATYPES.FRAME then -- assegno il profilo alle curve di outline local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId) while nOutlineId do local sName = EgtGetName( nOutlineId) -- recupero il tipo dei figli local nChildrenType = GetChildrenType( nOutlineId) -- a) se non definiti gestisco come anta if nChildrenType == WIN_CHILDREN_TYPES.NULL then if sName == WIN_BOTTOM then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_BOTTOM) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_TOP) end -- b) se anta elseif nChildrenType == WIN_CHILDREN_TYPES.SASH then -- verifico tipologia di anta contro cui poggia local vChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi') local nSashArea = EgtGetParent( EgtGetParent( vChildren[1])) local nSashType = EgtGetInfo( nSashArea, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL -- b1) alzante scorrevole if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE or nSashType == WIN_SASHTYPES.SLIDE_FIXED or nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then if sName == WIN_BOTTOM then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_BOTTOM) -- se le ante contro cui poggia sono tutte mobili devo aggiornare il profilo if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_BOTTOM_MOVABLEBACK) elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then for i = 2, #vChildren do local nSashArea = EgtGetParent( EgtGetParent( vChildren[i])) local nSashType = EgtGetInfo( nSashArea, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_BOTTOM_MOVABLEBACK) break elseif nSashType == WIN_SASHTYPES.SLIDE_FIXED then break end end end elseif sName == WIN_TOP then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_TOP) else if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_FIXED) end end -- b2) standard else if sName == WIN_BOTTOM then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_BOTTOM) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_TOP) end end -- c) se riempimento elseif nChildrenType == WIN_CHILDREN_TYPES.FILL then if sName == WIN_BOTTOM then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED_BOTTOM) EgtSetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, true) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FIXED_TOP) end -- d) se cambio profilo elseif nChildrenType == WIN_CHILDREN_TYPES.MIXED then EgtSetInfo( nOutlineId, WIN_PRF_CHANGE, true) if sName == WIN_BOTTOM then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_MIXED_BOTTOM) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_MIXED_TOP) end end nOutlineId = EgtGetNext( nOutlineId) end -- verifico se ci sono split e ne assegno il profilo local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) if nSplitLayerId then CalcSplitProfileType( nSplitLayerId, nAreaId) end -- SPLIT elseif nAreaType == WIN_AREATYPES.SPLIT or nAreaType == WIN_AREATYPES.NULL then -- verifico se ci sono split e ne assegno il profilo local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) if nSplitLayerId then CalcSplitProfileType( nSplitLayerId, nAreaId) end -- SASH elseif nAreaType == WIN_AREATYPES.SASH then -- verifico tipologia di anta ( battente, ricevente, alzante scorrevole) local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL -- imposto profili sash local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId) while nOutlineId do local sName = EgtGetName( nOutlineId) -- se non è definita tipologia if nSashType == WIN_SASHTYPES.NULL then if sName == WIN_BOTTOM then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_BOTTOM) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_TOP) end else -- verifico se deriva da una curva di split di tipo french ( e quindi deve avere profilo speciale e.g. battente/ricevente) local nSouId = EgtGetInfo( nOutlineId, WIN_SOU, 'i') local nSouPrevId local nSplitType repeat nSouPrevId = nSouId nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i') if nSouId then local sName = EgtGetName( nSouId) if sName == WIN_SPLIT then local nParentId = EgtGetParent( nSouId) nSplitType = EgtGetInfo( nParentId, WIN_SPLITTYPE, 'i') end end until not nSouId or nSplitType == WIN_SPLITTYPES.FRENCH if nSplitType == WIN_SPLITTYPES.FRENCH then -- setto info sulla curva per ricordare che deriva da un french split ( utile nel calcolo degli outlines) EgtSetInfo( nOutlineId, WIN_CRV_ON_FRENCH_SPLIT, true) -- a) battente/ricevente if nSashType == WIN_SASHTYPES.ACTIVE then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_ACTIVE) elseif nSashType == WIN_SASHTYPES.INACTIVE then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_INACTIVE) elseif nSashType == WIN_SASHTYPES.ACTIVE_OUT or nSashType == WIN_SASHTYPES.INACTIVE_OUT then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRENCH_OUT) elseif nSashType == WIN_SASHTYPES.ACTIVE_IN or nSashType == WIN_SASHTYPES.INACTIVE_IN then -- devo verificare il tipo dell'anta adiacente local nAdjSashType = FindAdjacentSashType( nSouId, nSouPrevId) if nSashType == WIN_SASHTYPES.ACTIVE_IN then if nAdjSashType == WIN_SASHTYPES.ACTIVE_OUT then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRENCH_IN) else -- adiacente è inactive EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_ACTIVE) end elseif nSashType == WIN_SASHTYPES.INACTIVE_IN then if nAdjSashType == WIN_SASHTYPES.INACTIVE_OUT then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRENCH_IN) else -- adiacente è active EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SASH_INACTIVE) end end -- b) alzante scorrevole elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then local nAdjSashType = FindAdjacentSashType( nSouId, nSouPrevId) if nAdjSashType == WIN_SASHTYPES.SLIDE_MOVABLE then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_ACTIVE_IN) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_ACTIVE) end elseif nSashType == WIN_SASHTYPES.SLIDE_FIXED then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_INACTIVE) elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_INACTIVE) end else -- a) alzante scorrevole if nSashType == WIN_SASHTYPES.SLIDE_MOVABLE then if sName == WIN_BOTTOM then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_BOTTOM) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_TOP) end elseif nSashType == WIN_SASHTYPES.SLIDE_FIXED then if sName == WIN_BOTTOM then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_FIXED_BOTTOM) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_FIXED_TOP) end elseif nSashType == WIN_SASHTYPES.SLIDE_MOVABLE_BACK then if sName == WIN_BOTTOM then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_BACK_BOTTOM) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_SLIDE_MOVABLE_BACK_TOP) end -- b) standard else if sName == WIN_BOTTOM then EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_BOTTOM) else EgtSetInfo( nOutlineId, WIN_PROFILETYPE, WIN_FRAME_TOP) end end end end nOutlineId = EgtGetNext( nOutlineId) end -- verifico se ci sono split local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) if nSplitLayerId then -- assegno tipo di profilo local nSplitId = EgtGetFirstInGroup( nSplitLayerId) EgtSetInfo( nSplitId, WIN_PROFILETYPE, WIN_SASH_SPLIT) end end end --------------------------------------------------------------------- -- funzione che cicla ricorsivamente su aree e sottoaree per impostare i tipi di profilo local function CalculateAreaProfileType( nAreaId) -- calcolo i profili per l'area corrente CalcProfileType( nAreaId) -- calcolo i profili per le eventuali sottoaree local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') while nChildAreaId do CalculateAreaProfileType( nChildAreaId) nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') end end ---------------------------------------------------------------------------------- ------------------------------ CALCOLO OUTLINE --------------------------------- ---------------------------------------------------------------------------------- -- funzione che calcola l'outline dall'area outline ( base outline) local function CalculateOutlineFromAreaOutline( nAreaId) local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') -- recupero il base outline e creo gruppo per outline local nAreaOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAOUTLINE) local nOutlineLayerId = EgtGroup( nAreaId) EgtSetName( nOutlineLayerId, WIN_OUTLINE) EgtSetStatus( nOutlineLayerId, GDB_ST.OFF) CopyInfo( nOutlineLayerId, nAreaOutlineLayerId, WIN_JOINTS) CopyInfo( nOutlineLayerId, nAreaOutlineLayerId, WIN_BOTTOMRAIL) -- FRAME if nAreaType == WIN_AREATYPES.FRAME then -- sistemo le info local nAreaOutlineId = EgtGetFirstInGroup( nAreaOutlineLayerId) while nAreaOutlineId do local nOutlineId = EgtCopyGlob( nAreaOutlineId, nOutlineLayerId) EgtSetInfo( nAreaOutlineId, WIN_COPY, nOutlineId) EgtSetInfo( nOutlineId, WIN_COPY, nAreaOutlineId) nAreaOutlineId = EgtGetNext( nAreaOutlineId) end -- se presente, copio split local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) if nBaseSplitLayerId then local nSplitLayerId = EgtCopy( nBaseSplitLayerId, nAreaId) EgtSetName( nSplitLayerId, WIN_SPLIT) EgtSetStatus( nSplitLayerId, GDB_ST.OFF) local nBaseSplitId = EgtGetFirstInGroup( nBaseSplitLayerId) local nSplitId = EgtGetFirstInGroup( nSplitLayerId) EgtSetInfo( nBaseSplitId, WIN_COPY, nSplitId) EgtSetInfo( nSplitId, WIN_COPY, nBaseSplitId) end -- SPLIT elseif nAreaType == WIN_AREATYPES.SPLIT or nAreaType == WIN_AREATYPES.NULL then -- recupero outline di livello precedente e lo copio pezzo per pezzo local nBaseOutlineId = EgtGetFirstInGroup( nAreaOutlineLayerId) while nBaseOutlineId do -- recupero la curva di outline corrispondente alla curva del base outline da cui deriva e la copio local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i') local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId) -- se deriva da split devo aggiornare il nome e setto il riferimento local sSouName = EgtGetName( nSouId) if sSouName == WIN_SPLIT then local sBaseName = EgtGetName( nBaseOutlineId) EgtSetName( nOutlineId, sBaseName) EgtSetInfo( nOutlineId, WIN_REF_SPLIT, nSouId) end -- sistemo le info EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId) EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId) EgtRemoveInfo( nOutlineId, WIN_CHILD) nBaseOutlineId = EgtGetNext( nBaseOutlineId) end -- taglio tutti i contorni TrimAndOrientOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) -- se presente, copio split local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) if nBaseSplitLayerId then local nSplitLayerId = EgtCopy( nBaseSplitLayerId, nAreaId) EgtSetName( nSplitLayerId, WIN_SPLIT) EgtSetStatus( nSplitLayerId, GDB_ST.OFF) local nBaseSplitId = EgtGetFirstInGroup( nBaseSplitLayerId) local nSplitId = EgtGetFirstInGroup( nSplitLayerId) EgtSetInfo( nBaseSplitId, WIN_COPY, nSplitId) EgtSetInfo( nSplitId, WIN_COPY, nBaseSplitId) EgtRemoveInfo( nSplitId, WIN_SOU) -- lo taglio con outline TrimSplitWithOutline( nSplitId) -- recupero tipo di profilo local sSplitProfile = EgtGetInfo( nSplitId, WIN_PROFILETYPE) -- se split interno ad anta devo alzarlo in z come l'anta che lo contiene if sSplitProfile == WIN_SASH_SPLIT then -- recupero l'anta local nSashAreaId = EgtGetParent( nAreaId) local nAreaType = EgtGetInfo( nSashAreaId, WIN_AREATYPE, 'i') while nAreaType ~= WIN_AREATYPES.SASH do nSashAreaId = EgtGetParent( nSashAreaId) nAreaType = EgtGetInfo( nSashAreaId, WIN_AREATYPE, 'i') end local nSashBaseOutlineLayerId = EgtGetFirstNameInGroup( nSashAreaId, WIN_AREAOUTLINE) local nSashBaseOutlineId = EgtGetFirstInGroup( nSashBaseOutlineLayerId) -- recupero il profilo dell'anta local sSashProfile = EgtGetInfo( nSashBaseOutlineId, WIN_PROFILETYPE) local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH) local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile) -- calcolo offset sulla z dell'anta local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd') -- sposto Split in Z EgtMove( nSplitId, Z_AX() * dSashZOffset) end end -- SASH elseif nAreaType == WIN_AREATYPES.SASH then -- recupero se anta battente ricevente local nSashType = EgtGetInfo( nAreaId, WIN_SASHTYPE, 'i') or WIN_SASHTYPES.NULL -- recupero gruppo profili anta e telaio local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) local nSashProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH) local nFrameProfileLayerId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_FRAME) -- ciclo su profilo disegnato anta local nBaseOutlineId = EgtGetFirstInGroup( nAreaOutlineLayerId) while nBaseOutlineId do -- recupero la curva di outline del base outline da cui deriva e la copio local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i') local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId) -- recupero profilo local sSashProfile = EgtGetInfo( nBaseOutlineId, WIN_PROFILETYPE) local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile) -- calcolo offset sulla z dell'anta local dSashZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd') -- sposto anta in Z EgtMove( nOutlineId, Z_AX() * dSashZOffset) -- sistemo le info EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId) EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId) EgtSetInfo( nOutlineId, WIN_PROFILETYPE, sSashProfile) EgtRemoveInfo( nOutlineId, WIN_PRF_CHANGE) EgtRemoveInfo( nOutlineId, WIN_REF_SPLIT) -- verifico se outline e' segmento battente o ricevente ( che quindi deriva da split di tipo french) local bOnFrenchSplit = EgtGetInfo( nBaseOutlineId, WIN_CRV_ON_FRENCH_SPLIT, 'b') or false -- se outline non è segmento battente o ricevente necessita di offset if not bOnFrenchSplit then -- recupero a ritroso il profilo dell'elemento del frame su cui poggia local nFrameBaseOutlineId = nSouId local sFrameProfile = EgtGetInfo( nFrameBaseOutlineId, WIN_PROFILETYPE) while not sFrameProfile and nFrameBaseOutlineId do nFrameBaseOutlineId = EgtGetInfo( nFrameBaseOutlineId, WIN_SOU , 'i') sFrameProfile = EgtGetInfo( nFrameBaseOutlineId or GDB_ID.NULL, WIN_PROFILETYPE) end local nFrameProfileId = EgtGetFirstNameInGroup( nFrameProfileLayerId, sFrameProfile) -- calcolo il box del riferimento del profilo del frame local b3FrameProfile = GetProfileLocalBox( nFrameProfileId) -- calcolo offset perpendicolare local sOverlapInfo = EgtIf( EgtGetName( nOutlineId) == WIN_BOTTOM, WIN_SASH_BOTTOM_OVERLAP, WIN_SASH_TOP_OVERLAP) local dOverlap = EgtGetInfo( nFrameProfileId, sOverlapInfo, 'd') local dSashPerpOffset = abs( b3FrameProfile:getMin():getX()) - dOverlap -- faccio offset EgtOffsetCurve( nOutlineId, - dSashPerpOffset) end nBaseOutlineId = EgtGetNext( nBaseOutlineId) end -- accorcio gli offset TrimAndOrientOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) -- se presente, copio split local nBaseSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_BASESPLIT) if nBaseSplitLayerId then local nBaseSplitId = EgtGetFirstInGroup( nBaseSplitLayerId) -- creo copia local nSplitLayerId = EgtCopy( nBaseSplitLayerId, nAreaId) EgtSetName( nSplitLayerId, WIN_SPLIT) EgtSetStatus( nSplitLayerId, GDB_ST.OFF) local nSplitId = EgtGetFirstInGroup( nSplitLayerId) EgtSetInfo( nBaseSplitId, WIN_COPY, nSplitId) EgtSetInfo( nSplitId, WIN_COPY, nBaseSplitId) EgtRemoveInfo( nSplitId, WIN_SOU) -- la taglio con outline TrimSplitWithOutline( nSplitId) -- calcolo offset sulla z dal profilo dell'anta local nPrevId = EgtGetInfo( nBaseSplitId, WIN_SPLIT_STARTINTERS, 'i') local sSashProfile = EgtGetInfo( nPrevId, WIN_PROFILETYPE) local nSashProfileId = EgtGetFirstNameInGroup( nSashProfileLayerId, sSashProfile) local dSplitZOffset = EgtGetInfo( nSashProfileId, WIN_DELTA, 'd') -- sposto split in Z EgtMove( nSplitId, Z_AX() * dSplitZOffset) end -- FILL elseif nAreaType == WIN_AREATYPES.FILL then -- ciclo su BaseArea riempimento local nBaseOutlineId = EgtGetFirstInGroup( nAreaOutlineLayerId) while nBaseOutlineId do -- recupero la curva di outline del base outline da cui deriva e la copio local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i') local nCopyId = EgtGetInfo( nSouId, WIN_COPY, 'i') local nOutlineId = EgtCopy( nCopyId, nOutlineLayerId) -- sistemo le info EgtSetInfo( nBaseOutlineId, WIN_COPY, nOutlineId) EgtSetInfo( nOutlineId, WIN_COPY, nBaseOutlineId) -- recupero a ritroso il profilo dell'elemento su cui poggia ( anta, split o frame) local nParentBaseOutlineId = nSouId local sParentProfile = EgtGetInfo( nParentBaseOutlineId, WIN_PROFILETYPE) while not sParentProfile and nParentBaseOutlineId do nParentBaseOutlineId = EgtGetInfo( nParentBaseOutlineId, WIN_SOU , 'i') sParentProfile = EgtGetInfo( nParentBaseOutlineId or GDB_ID.NULL, WIN_PROFILETYPE) end local nParentOutlineId = EgtGetInfo( nParentBaseOutlineId, WIN_COPY, 'i') local nParentProfileId = GetOutlineProfileId( nParentOutlineId, true) -- calcolo il box del riferimento del profilo del frame local b3FrameProfile = GetProfileLocalBox( nParentProfileId) -- calcolo offset perpendicolare e sulla z dell'anta local dOverlap = EgtGetInfo( nParentProfileId, WIN_FILLOVERLAP, 'd') local bMixedSplit = ( EgtGetInfo( nParentOutlineId, WIN_PRF_CHANGE, 'b') or false) and EgtGetName( nParentOutlineId) == WIN_SPLIT local dDimRef = EgtIf( bMixedSplit, b3FrameProfile:getMax():getX(), b3FrameProfile:getMin():getX()) local dFillPerpOffset = abs( dDimRef) - dOverlap local dFillZOffset = EgtGetInfo( nParentProfileId, WIN_FILLDELTA, 'd') -- faccio offset e muovo in z EgtOffsetCurve( nOutlineId, - dFillPerpOffset) EgtMove( nOutlineId, Z_AX() * dFillZOffset) nBaseOutlineId = EgtGetNext( nBaseOutlineId) end -- accorcio gli offset TrimAndOrientOrderedCurves( EgtGetAllInGroup( nOutlineLayerId), true) end end --------------------------------------------------------------------- -- funzione che cicla ricorsivamente su aree e sottaree per calcolare gli outlines local function CalculateAreaOutline( nAreaId) -- calcolo outlines per l'area corrente CalculateOutlineFromAreaOutline( nAreaId) -- calcolo outlines per le eventuali sottoaree local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') while nChildAreaId do CalculateAreaOutline( nChildAreaId) nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') end end ---------------------------------------------------------------------------------- ------------------------ FUNZIONI AUX PER CALCOLO PEZZI ------------------------ ---------------------------------------------------------------------------------- -- funzione che restituisce il WIN_PRF in base al nome della curva local function GetOutlineProfileType( nOutlineId, bBottomRail) -- ricavo tipo dal nome local sName = EgtGetName( nOutlineId) local nProfileType = WIN_PRF.NULL if sName == WIN_TOP then nProfileType = WIN_PRF.TOP elseif sName == WIN_BOTTOM then nProfileType = EgtIf( bBottomRail, WIN_PRF.BOTTOMRAIL, WIN_PRF.BOTTOM) elseif sName == WIN_LEFT then nProfileType = WIN_PRF.LEFT elseif sName == WIN_RIGHT then nProfileType = WIN_PRF.RIGHT elseif sName == WIN_SPLIT then nProfileType = WIN_PRF.SPLIT end return nProfileType end --------------------------------------------------------------------- -- funzione che calcola gli outline precedenti e successivi nel caso di split local function GetSplitOtherOutline( nSplitId, nSurfSplit, nOutlineId, bPrevOrNext) local vOutlineIds = {} -- verifico se devo controllare la curva precedente o successiva dell'outline corrente local nCrv local bPrevOutline = false local ptRef = EgtIf( bPrevOrNext, EgtSP( nSplitId), EgtEP( nSplitId)) local dPar = EgtCurveParamAtPoint( nOutlineId, ptRef) local dLenInt = EgtCurveLengthAtParam( nOutlineId, dPar) local dLenTot = EgtCurveLength( nOutlineId) -- se l'intersezione è più vicina alla fine dell'outline devo controllare il suo next, altrimenti il suo prev if abs( dLenTot - dLenInt) < dLenInt then nCrv = EgtGetNext( nOutlineId) or EgtGetFirstInGroup( EgtGetParent( nOutlineId)) else bPrevOutline = true nCrv = EgtGetPrev( nOutlineId) or EgtGetLastInGroup( EgtGetParent( nOutlineId)) end -- recupero il geo associato e costruisco superficie test local nPartId = FindAssociatedPart( nCrv) local nGeoId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local nGeoOut = EgtGetFirstNameInGroup( nGeoId, WIN_GEO_OUT) local nGeoIn = EgtGetFirstNameInGroup( nGeoId, WIN_GEO_IN) local nCrv1 = EgtCopyGlob( nGeoOut, nGeoId) local nCrv2 = EgtCopyGlob( nGeoIn, nGeoId) local nCompoTest = EgtCurveCompo( nGeoId, nCrv1) local dParTest = 0.2 if bPrevOutline then -- considero solo la parte finale del pezzo EgtTrimCurveStartAtParam( nCompoTest, 1 - dParTest) EgtAddCurveCompoLine( nCompoTest, EgtSP( nCrv2)) EgtTrimCurveEndAtParam( nCrv2, dParTest) else -- considero solo la parte iniziale del pezzo EgtTrimCurveEndAtParam( nCompoTest, dParTest) EgtTrimCurveStartAtParam( nCrv2, 1 - dParTest) EgtAddCurveCompoLine( nCompoTest, EgtSP( nCrv2)) end EgtAddCurveCompoCurve( nCompoTest, nCrv2) EgtCloseCurveCompo( nCompoTest) local nSurfTest = EgtSurfFlatRegion( nGeoId, { nCompoTest}) -- verifico se le due regioni interferiscono if EgtSurfFrTestExternal( nSurfSplit, nSurfTest) then vOutlineIds = { nOutlineId} else -- aggiungo la curva trovata tra le curve di outline da considerare rispettando l'ordinamento if bPrevOutline then vOutlineIds = { nCrv, nOutlineId} else vOutlineIds = { nOutlineId, nCrv} end end EgtErase( nCompoTest) EgtErase( nSurfTest) return vOutlineIds end --------------------------------------------------------------------- -- funzione che recupera gli outline precedenti e successivi local function GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) local vPrevOutlineId = {} local vNextOutlineId = {} if nProfileType ~= WIN_PRF.SPLIT then vPrevOutlineId = { EgtGetPrev( nOutlineId) or EgtGetLastInGroup( nOutlineLayerId)} vNextOutlineId = { EgtGetNext( nOutlineId) or EgtGetFirstInGroup( nOutlineLayerId)} else -- se split recupero tutte le curve di base outline che lo tagliano local vPrevBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_STARTINTERS, 'vi') for i = 1, #vPrevBaseOutlineId do -- recupero l'outline associato al base outline che lo taglia table.insert( vPrevOutlineId, EgtGetInfo( vPrevBaseOutlineId[i], WIN_COPY, 'i')) end local vNextBaseOutlineId = EgtGetInfo( nOutlineId, WIN_SPLIT_ENDINTERS, 'vi') for i = 1, #vNextBaseOutlineId do table.insert( vNextOutlineId, EgtGetInfo( vNextBaseOutlineId[i], WIN_COPY, 'i')) end -- se lo split è tagliato da una sola curva di base outline, verifico se coinvolge altre curve if #vPrevBaseOutlineId == 1 or #vNextBaseOutlineId == 1 then -- costruisco una regione approssimata per il pezzo dello split local nGrp = EgtGetParent( nOutlineId) local nSplitProfileId = GetOutlineProfileId( nOutlineId, false) local b3Profile = GetProfileLocalBox( nSplitProfileId) local nCrvOut = EgtCopyGlob( nOutlineId, nGrp) local nCrvIn = EgtCopyGlob( nOutlineId, nGrp) EgtOffsetCurve( nCrvOut, b3Profile:getMax():getX()) EgtOffsetCurve( nCrvIn, b3Profile:getMin():getX()) EgtInvertCurve( nCrvIn) local nCompoTest = EgtCurveCompo( nGrp, nCrvOut) EgtAddCurveCompoLine( nCompoTest, EgtSP( nCrvIn)) EgtAddCurveCompoCurve( nCompoTest, nCrvIn) EgtCloseCurveCompo( nCompoTest) local nSurfTest = EgtSurfFlatRegion( nGrp, nCompoTest) -- se necessario aggiorno il prev if #vPrevBaseOutlineId == 1 and EgtGetName( vPrevBaseOutlineId[1]) ~= WIN_SPLIT then vPrevOutlineId = GetSplitOtherOutline( nOutlineId, nSurfTest, vPrevOutlineId[1], true) end -- se necessario aggiorno il next if #vNextOutlineId == 1 and EgtGetName( vNextBaseOutlineId[1]) ~= WIN_SPLIT then vNextOutlineId = GetSplitOtherOutline( nOutlineId, nSurfTest, vNextOutlineId[1], false) end EgtErase( nSurfTest) EgtErase( nCompoTest) end end return vPrevOutlineId, vNextOutlineId end --------------------------------------------------------------------- -- funzione che restituisce il tipo di controprofilo dell'outline adiacente local function GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId) local sPrevCtrIn = WIN_CTRIN -- gestione particolare del caso di split o cambio profilo if not EgtGetFirstNameInGroup( nPrevProfileId, sPrevCtrIn) then local nRefSplitId = EgtGetInfo( nPrevOutlineId, WIN_REF_SPLIT, 'i') if nRefSplitId or EgtGetName( nPrevOutlineId) == WIN_SPLIT then -- 1) split -- verifico da quale lato dello split originale si trova l'outline per decidere quale controprofilo considerare local _, _, nSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nRefSplitId or nPrevOutlineId, Z_AX()) if nSide == 1 then sPrevCtrIn = WIN_CTRIN .. '1' -- dx else sPrevCtrIn = WIN_CTRIN .. '2' -- sx end else -- 2) pezzo del telaio con cambio profilo -- il profilo da usare dipende dal pezzo corrente: se ha figli di tipo fill allora è legato alla parte fill del cambio profilo, se ha figli di tipo sash è legato alla parte sash, -- se ha entrambe le tipologie di figli allora è mixed split e va considerata la parte sash ( perchè è quella utilizzata per tagliare il pezzo) local vSashChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi') if vSashChildren then sPrevCtrIn = WIN_SASH .. WIN_CTRIN else sPrevCtrIn = WIN_FILL .. WIN_CTRIN end end end return sPrevCtrIn end --------------------------------------------------------------------- -- funzione che crea la superficie corrispondente al Geo di un pezzo gestendo i casi di autointersezione local function CreateGeoArea( nGeoLayId, nDestLayId) -- recupero le curve left e right e verifico se hanno orientamento coerente ( quindi non generano autointersezioni) local bAutointers = false local vLeft = EgtGetNameInGroup( nGeoLayId, WIN_LEFT) local vRight = EgtGetNameInGroup( nGeoLayId, WIN_RIGHT) if #vLeft == 2 and not AreSamePointApprox( EgtEP( vLeft[1]), EgtSP( vLeft[2])) then bAutointers = true -- se orientamento non coerente devo ignorare la prima curva vLeft[1] = GDB_ID.NULL end if #vRight == 2 and not AreSamePointApprox( EgtEP( vRight[1]), EgtSP( vRight[2])) then bAutointers = true -- se orientamento non coerente devo ignorare la seconda curva vRight[2] = GDB_ID.NULL end local nCompoId if not bAutointers then -- se no autointersezioni costruisco il bordo del geo usando direttamente le sue curve local vCrvs = EgtGetAllInGroup( nGeoLayId) nCompoId = EgtCurveCompo( nDestLayId, vCrvs, false) else -- nel caso di autointersezione devo ignorare le curve left e right con orientamento non coerente local vGeoCrvs = {} local nOutId = EgtGetFirstNameInGroup( nGeoLayId, WIN_GEO_OUT) vGeoCrvs[1] = EgtCopyGlob( nOutId, nDestLayId) for i = 1, #vRight do if vRight[i] ~= GDB_ID.NULL then table.insert( vGeoCrvs, EgtCopyGlob( vRight[i], nDestLayId)) end end local nInId = EgtGetFirstNameInGroup( nGeoLayId, WIN_GEO_IN) table.insert( vGeoCrvs, EgtCopyGlob( nInId, nDestLayId)) for i = 1, #vLeft do if vLeft[i] ~= GDB_ID.NULL then table.insert( vGeoCrvs, EgtCopyGlob( vLeft[i], nDestLayId)) end end -- taglio le curve TrimAndOrientOrderedCurves( vGeoCrvs, false) -- creo compo nCompoId = EgtCurveCompo( nDestLayId, vGeoCrvs) end local nArea = EgtSurfFlatRegion( nDestLayId, nCompoId) EgtErase( nCompoId) return nArea end ---------------------------------------------------------------------------------- -------------------------------- GEO ------------------------------------------- ---------------------------------------------------------------------------------- -- funzione che dato il tipo di pezzo e di giunzione, restituisce se e' corto, lungo o angolato local function CalcPartJointType( nProfileType, JointType) if JointType == WIN_JNT.ANGLED then return WIN_PART_JNT.ANGLED end if nProfileType == WIN_PRF.BOTTOMRAIL or nProfileType == WIN_PRF.SPLIT then return WIN_PART_JNT.SHORT elseif nProfileType == WIN_PRF.BOTTOM or nProfileType == WIN_PRF.TOP then if JointType == WIN_JNT.FULL_H then return WIN_PART_JNT.FULL elseif JointType == WIN_JNT.FULL_V then return WIN_PART_JNT.SHORT end elseif nProfileType == WIN_PRF.LEFT or nProfileType == WIN_PRF.RIGHT then if JointType == WIN_JNT.FULL_V then return WIN_PART_JNT.FULL elseif JointType == WIN_JNT.FULL_H then return WIN_PART_JNT.SHORT end end end --------------------------------------------------------------------- -- funzione che crea il gruppo con i profili di un pezzo local function CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType) -- creo gruppo per i profili local nProfileLayerId = EgtGroup( nPartId) EgtSetName( nProfileLayerId, WIN_PROFILE) EgtSetStatus( nProfileLayerId, GDB_ST.OFF) -- recupero profilo principale e ne creo copia local nOrigMainProfileId = GetOutlineProfileId( nOutlineId, nProfileType == WIN_PRF.BOTTOMRAIL) local nMainProfileId = EgtCopy( nOrigMainProfileId, nProfileLayerId) local sMainProfileType = EgtGetName( nMainProfileId) EgtSetInfo( nMainProfileId, WIN_PRF_TYPE, sMainProfileType) EgtSetName( nMainProfileId, WIN_PRF_MAIN) -- recupero profili start e ne creo copia -- se il tipo corrente è split il pezzo va tagliato con il bottomrail, altrimenti con il bottom for i = 1, #vPrevOutlineId do local nOrigStartProfileId = GetOutlineProfileId( vPrevOutlineId[i], nProfileType == WIN_PRF.SPLIT) local nStartProfileId = EgtCopy( nOrigStartProfileId, nProfileLayerId) local sStartProfileType = EgtGetName( nStartProfileId) EgtSetInfo( nStartProfileId, WIN_PRF_TYPE, sStartProfileType) EgtSetName( nStartProfileId, WIN_PRF_START) end -- recupero profili end e ne creo copia for i = 1, #vNextOutlineId do local nOrigEndProfileId = GetOutlineProfileId( vNextOutlineId[i], nProfileType == WIN_PRF.SPLIT) local nEndProfileId = EgtCopy( nOrigEndProfileId, nProfileLayerId) local sEndProfileType = EgtGetName( nEndProfileId) EgtSetInfo( nEndProfileId, WIN_PRF_TYPE, sEndProfileType) EgtSetName( nEndProfileId, WIN_PRF_END) end -- recupero le info di pinzaggio dal profilo di estrusione CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFY_1, 0) CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFZ_1, 0) CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFY_2, 0) CopyInfo( nPartId, nMainProfileId, WIN_PRC_OFFZ_2, 0) CopyInfo( nPartId, nMainProfileId, WIN_PRC_CLAMPV_1, 0) CopyInfo( nPartId, nMainProfileId, WIN_PRC_CLAMPV_2, 0) return nProfileLayerId end --------------------------------------------------------------------- local function GetDeltaProfile( nProfileId, sCtrIn) local dCPDelta = 0 local nSectionFrId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frSectionFrame = EgtFR( nSectionFrId, GDB_ID.ROOT) local nCPId = EgtGetFirstNameInGroup( nProfileId, sCtrIn) local b3CP = EgtGetBBoxRef( nCPId, GDB_BB.STANDARD, frSectionFrame) if sCtrIn == WIN_CTRIN .. 1 then dCPDelta = abs( b3CP:getMin():getX()) else dCPDelta = abs( b3CP:getMax():getX()) end return dCPDelta end --------------------------------------------------------------------- -- funzione che crea le curve del geo local function CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId) local nCurrProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) -- calcolo spostamento della curva iniziale dovuto a posizione riferimento local b3CurrProfileFrame = GetProfileLocalBox( nCurrProfileId) local dCurrOffset = b3CurrProfileFrame:getMax():getX() -- creo copie degli outline e le offsetto opportunamente -- curva out local nCurrCurveId = EgtCopy( nOutlineId, nGeoLayerId) EgtOffsetCurve( nCurrCurveId, dCurrOffset) EgtSetName( nCurrCurveId, WIN_GEO_OUT) local nSemiProfileOut = EgtGetFirstNameInGroup( nCurrProfileId, WIN_OUT) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '1') EgtSetInfo( nCurrCurveId, WIN_SEMI_PROFILE, nSemiProfileOut) -- cruva in local nCurrOffsetId = EgtCopy( nOutlineId, nGeoLayerId) EgtOffsetCurve( nCurrOffsetId, dCurrOffset - b3CurrProfileFrame:getDimX()) EgtInvertCurve( nCurrOffsetId) EgtSetName( nCurrOffsetId, WIN_GEO_IN) local nSemiProfileIn = EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN) or EgtGetFirstNameInGroup( nCurrProfileId, WIN_IN .. '2') or EgtGetFirstNameInGroup( nCurrProfileId, WIN_MIXED_COMMON .. WIN_IN) EgtSetInfo( nCurrOffsetId, WIN_SEMI_PROFILE, nSemiProfileIn) -- curve left local vPrevProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START) for i = 1, #vPrevOutlineId do local nPrevCurveId local nPrevSemiProfile if nStartPartJointType == WIN_PART_JNT.ANGLED then -- calcolo la bisettrice local vtMedia = ( ( EgtSV( nOutlineId) - EgtEV( vPrevOutlineId[i])) / 2) if not vtMedia:normalize() then vtMedia = EgtSV( nOutlineId) vtMedia:rotate( Z_AX(), 90) end nPrevCurveId = EgtLinePVL( nGeoLayerId, EgtSP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX()) EgtInvertCurve( nPrevCurveId) else nPrevCurveId = EgtCopy( vPrevOutlineId[i], nGeoLayerId) if nStartPartJointType == WIN_PART_JNT.SHORT then local sCtrIn = GetProfileCtrIn( vPrevOutlineId[i], nOutlineId, vPrevProfileId[i]) local dCPDelta = GetDeltaProfile( vPrevProfileId[i], sCtrIn) EgtOffsetCurve( nPrevCurveId, - dCPDelta) -- ricavo il semiprofilo associato nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], sCtrIn) else nPrevSemiProfile = EgtGetFirstNameInGroup( vPrevProfileId[i], WIN_OUT) end end EgtSetName( nPrevCurveId, WIN_GEO_LEFT) EgtSetInfo( nPrevCurveId, WIN_SEMI_PROFILE, nPrevSemiProfile) EgtSetInfo( nPrevCurveId, WIN_REF_OUTLINE, vPrevOutlineId[i]) EgtRelocateGlob( nPrevCurveId, nGeoLayerId, GDB_IN.LAST_SON) end -- curve right local vNextProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END) for i = 1, #vNextOutlineId do local nNextCurveId local nNextSemiProfile if nEndPartJointType == WIN_PART_JNT.ANGLED then -- calcolo la bisettrice local vtMedia = ( ( EgtSV( vNextOutlineId[i]) - EgtEV( nOutlineId)) / 2) if not vtMedia:normalize() then vtMedia = EgtEV( nOutlineId) vtMedia:rotate( Z_AX(), 90) end nNextCurveId = EgtLinePVL( nGeoLayerId, EgtEP( nOutlineId), vtMedia, 3 * b3CurrProfileFrame:getDimX()) else nNextCurveId = EgtCopy( vNextOutlineId[i], nGeoLayerId) if nEndPartJointType == WIN_PART_JNT.SHORT then local sCtrIn = GetProfileCtrIn( vNextOutlineId[i], nOutlineId, vNextProfileId[i]) local dCPDelta = GetDeltaProfile( vNextProfileId[i], sCtrIn) EgtOffsetCurve( nNextCurveId, - dCPDelta) -- ricavo il semiprofilo associato nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], sCtrIn) else nNextSemiProfile = EgtGetFirstNameInGroup( vNextProfileId[i], WIN_OUT) end end EgtSetName( nNextCurveId, WIN_GEO_RIGHT) EgtSetInfo( nNextCurveId, WIN_SEMI_PROFILE, nNextSemiProfile) EgtSetInfo( nNextCurveId, WIN_REF_OUTLINE, vNextOutlineId[i]) EgtRelocateGlob( nNextCurveId, nCurrOffsetId, GDB_IN.BEFORE) end -- trim delle curve TrimAndOrientOrderedCurves( EgtGetAllInGroup( nGeoLayerId), false) -- salvo spessore serramento nel gruppo local dGeoWidth = b3CurrProfileFrame:getDimX() EgtSetInfo( nGeoLayerId, WIN_GEOWIDTH, dGeoWidth) end --------------------------------------------------------------------- -- funzione che calcola l'ingombro dei pezzi del telaio local function CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType) -- creo layer per ingombro local nGeoLayerId = EgtGroup( nPartId) EgtSetName( nGeoLayerId, WIN_GEO) -- recupero outline precedenti e successivi ( solo nel caso di split possono essere più di uno) local vPrevOutlineId, vNextOutlineId = GetPrevNextOutline( nProfileType, nOutlineId, nOutlineLayerId) EgtSetInfo( nOutlineId, WIN_PREV_OUTLINES, vPrevOutlineId) EgtSetInfo( nOutlineId, WIN_NEXT_OUTLINES, vNextOutlineId) -- recupero il tipo di giunzioni local nStartJointType local nEndJointType if nProfileType == WIN_PRF.SPLIT or nProfileType == WIN_PRF.BOTTOMRAIL then -- non serve settare dei valori per StartJointType ed EndJointType perchè in CalcPartJointType la loro giunzione viene settata a short else -- recupero i joints dal vettore local vJoints = EgtGetInfo( nOutlineLayerId, WIN_JOINTS, 'vi') nStartJointType = vJoints[nOutlineCrvNbr] nEndJointType = vJoints[nOutlineCrvNbr + 1] or vJoints[1] -- se giunzione diversa da bisettrice e arco a tutto sesto oppure elementi entrambi dello stesso tipo, forzo il tipo a bisettrice if nStartJointType ~= WIN_JNT.ANGLED and ( AreSameVectorApprox( EgtEV( vPrevOutlineId[1]), EgtSV( nOutlineId)) or EgtGetName( nOutlineId) == EgtGetName( vPrevOutlineId[1])) then nStartJointType = WIN_JNT.ANGLED end if nEndJointType ~= WIN_JNT.ANGLED and ( AreSameVectorApprox( EgtEV( nOutlineId), EgtSV( vNextOutlineId[1])) or EgtGetName( nOutlineId) == EgtGetName( vNextOutlineId[1])) then nEndJointType = WIN_JNT.ANGLED end end -- correzione per caso del triangolo local nProfileTypeS = nProfileType local nProfileTypeE = nProfileType if nProfileType == WIN_PRF.TOP then -- se lato top contro lato bottom, il lato top deve essere trattato come un left/right nel calcolo della giunzione if EgtGetName( vPrevOutlineId[1]) == WIN_BOTTOM then nProfileTypeS = WIN_PRF.LEFT end if EgtGetName( vNextOutlineId[1]) == WIN_BOTTOM then nProfileTypeE = WIN_PRF.LEFT end end -- calcolo il tipo di giunzione per la parte local nStartPartJointType = CalcPartJointType( nProfileTypeS, nStartJointType) local nEndPartJointType = CalcPartJointType( nProfileTypeE, nEndJointType) -- salvo il valore di start joint su outline per calcolo dowels -- se bottomrail è sicuramente short quindi non salvo il valore che sovrascriverebbe quello del pezzo bottom ( che potrebbe essere short o full) if nProfileType ~= WIN_PRF.BOTTOMRAIL then EgtSetInfo( nOutlineId, WIN_STARTJOINT, nStartPartJointType) end -- creo il gruppo con i profili del pezzo local nProfileLayerId = CalcProfiles( nPartId, nOutlineId, vPrevOutlineId, vNextOutlineId, nProfileType) -- creo lati dell'outline CreateFrameGeo( nOutlineId, vPrevOutlineId, vNextOutlineId, nStartPartJointType, nEndPartJointType, nGeoLayerId, nProfileLayerId) end --------------------------------------------------------------------- -- funzione che calcola l'ingombro del fill local function CalcFillGeo( nPartId, nOutlineLayerId) -- creo layer per ingombro local nGeoLayerId = EgtGroup( nPartId) EgtSetName( nGeoLayerId, WIN_GEO) -- copio lati da Outline local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId) while nOutlineId do EgtCopy( nOutlineId, nGeoLayerId) nOutlineId = EgtGetNext( nOutlineId) end -- recupero e salvo spessore vetro local nProfileLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) local nSashProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_SASH) local dGlassThickness = EgtGetInfo( nSashProfileId, WIN_GLASSTHICKNESS, 'd') EgtSetInfo( nGeoLayerId, WIN_GEOWIDTH, dGlassThickness) return nGeoLayerId end ---------------------------------------------------------------------------------- ----------------------- CURVE AUX PER CAMBIO PROFILO ----------------------------- ---------------------------------------------------------------------------------- -- funzione che individua e crea i diversi tratti uniformi della curva di outline local function CalcMixedOutlines( nPartId, nOutlineId) -- creo gruppo dove salvare i sottotratti local nGrp = EgtGroup( nPartId) EgtSetName( nGrp, WIN_MIXED_OUTLINES) EgtSetStatus( nGrp, GDB_ST.OFF) -- recupero i tratti di tipo sash e li concateno local vSashChildren = EgtGetInfo( nOutlineId, WIN_SASH_CHILDREN, 'vi') local vSash = {} for i = 1, #vSashChildren do local nCrv = EgtCopyGlob( vSashChildren[i], nGrp) table.insert( vSash, nCrv) end local nCrvS, nCntS = EgtCurveCompoByReorder( nGrp, vSash, EgtSP( nOutlineId)) for nId = nCrvS, nCrvS + nCntS - 1 do EgtSetName( nId, WIN_SASH) end -- recupero i tratti di tipo fill e li concateno local vFillChildren = EgtGetInfo( nOutlineId, WIN_FILL_CHILDREN, 'vi') local vFill = {} for i = 1, #vFillChildren do local nCrv = EgtCopyGlob( vFillChildren[i], nGrp) table.insert( vFill, nCrv) end local nCrvF, nCntF = EgtCurveCompoByReorder( nGrp, vFill, EgtSP( nOutlineId)) for nId = nCrvF, nCrvF + nCntF - 1 do EgtSetName( nId, WIN_FILL) end -- riordino le curve nel gruppo per ricostruire l'outline EgtReorderCurvesInGroup( nGrp, EgtSP( nOutlineId)) -- creo associazione tra le sottocurve di outline e gli split che le separano : -- recupero tutti gli split coinvolti local nBaseOutline = EgtGetInfo( nOutlineId, WIN_COPY, 'i') local vStack = { nBaseOutline} local vSplitIds = {} local i = 1 while vStack[i] do -- recupero il tipo di area local nAreaId = EgtGetParent( EgtGetParent( vStack[i])) local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') if nAreaType ~= WIN_AREATYPES.SASH and nAreaType ~= WIN_AREATYPES.FILL then -- salvo il suo eventuale split local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) if nSplitLayerId then local nSplitId = EgtGetFirstInGroup( nSplitLayerId) table.insert( vSplitIds, nSplitId) end -- analizzo eventuali figli local vChildren = EgtGetInfo( vStack[i], WIN_CHILD, 'vi') or {} vStack = EgtJoinTables( vStack, vChildren) end i = i + 1 end -- associo le curve con lo split che le taglia nel loro punto finale local vCrvs = EgtGetAllInGroup( nGrp) for i = 1, #vSplitIds do local ptS = EgtSP( vSplitIds[i]) local ptE = EgtEP( vSplitIds[i]) for j = 1, #vCrvs - 1 do local ptTest = EgtEP( vCrvs[j]) if AreSamePointApprox( ptS, ptTest) then EgtSetInfo( vSplitIds[i], WIN_MIXED_REF_START, vCrvs[j]) EgtSetInfo( vCrvs[j], WIN_MIXED_SPLIT_REF, vSplitIds[i]) break elseif AreSamePointApprox( ptE, ptTest) then EgtSetInfo( vSplitIds[i], WIN_MIXED_REF_END, vCrvs[j]) EgtSetInfo( vCrvs[j], WIN_MIXED_SPLIT_REF, vSplitIds[i]) break end end end return nGrp end --------------------------------------------------------------------- -- funzione che crea la curva di riferimento sulla giunzione tra il pezzo di split e il pezzo di telaio con cambio profilo local function CalcMixedIntersections( nPartId, nOutline, vOutlines) local nGrp = EgtGroup( nPartId) EgtSetName( nGrp, WIN_MIXED_INTERSECTIONS) EgtSetStatus( nGrp, GDB_ST.OFF) -- recupero il profilo dell'outline local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) for i = 1, #vOutlines - 1 do -- recupero la curva di split che separa i due tratti di outline local nSplitId = EgtGetInfo( vOutlines[i], WIN_MIXED_SPLIT_REF, 'i') local nSplitProfileId = GetOutlineProfileId( nSplitId, false) -- verifico ordinamento local bSashFill = ( EgtGetName( vOutlines[i]) == WIN_SASH) -- ricavo il punto di incontro tra le due parti dei profili che vanno contro il vetro local nCrv1 = EgtCopyGlob( nSplitId, nGrp) local dDeltaFixedSplit = EgtGetInfo( nSplitProfileId, WIN_FIXED_REF, 'd') EgtOffsetCurve( nCrv1, dDeltaFixedSplit) local nCrv2 = EgtCopyGlob( nOutline, nGrp) local dDeltaFixedFrame = EgtGetInfo( nMainProfileId, WIN_FIXED_REF, 'd') EgtOffsetCurve( nCrv2, - dDeltaFixedFrame) local ptRef1 = EgtIP( nCrv1, nCrv2, ORIG()) -- ricavo il punto di incontro tra il taglio a 45° e la parte del telaio contro anta -- TO DO : capire come gestire correttamente la rotazione nel caso di arco local dParRef = EgtCurveParamAtPoint( nCrv2, ptRef1) local vtDir45 = EgtUV( nCrv2, dParRef, -1) vtDir45:rotate( Z_AX(), EgtIf( bSashFill, 225, -45)) local nCrv3 = EgtLinePVL( nGrp, ptRef1, vtDir45, 100) local nCrv4 = EgtCopyGlob( nOutline, nGrp) local dDeltaSashFrame = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '1', 'd') EgtOffsetCurve( nCrv4, - dDeltaSashFrame) local ptRef2 = EgtIP( nCrv3, nCrv4, ORIG()) -- curva di intersezione da usare come riferimento per i conti successivi local nCrv = EgtCurveCompoFromPoints( nGrp, { ptRef1, ptRef2}) -- calcolo il raccordo local dRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '1', 'd') local dParFillet = EgtCurveParamAtPoint( nCrv4, ptRef2) dParFillet = dParFillet + EgtIf( bSashFill, -10, 10) * GEO.EPS_SMALL local nFillet = EgtCurveFillet( nGrp, nCrv, EgtUP( nCrv1, 0.9), nCrv4, EgtUP( nCrv4, dParFillet), dRad, true) or GDB_ID.NULL EgtAddCurveCompoCurve( nCrv, nFillet) -- cancello curve di costruzione EgtErase( { nCrv1, nCrv2, nCrv3, nCrv4}) -- assegno riferimento EgtSetInfo( vOutlines[i], WIN_MIXED_INTERS_REF, nCrv) end end --------------------------------------------------------------------- -- funzione che calcola curve ausiliarie per la gestione del cambio profilo local function CalcMixedFrameCurves( nPartId, nOutlineId) -- calcolo i sottotratti uniformi della curva di outline local nOutlinesGrp = CalcMixedOutlines( nPartId, nOutlineId) local vCrvs = EgtGetAllInGroup( nOutlinesGrp) -- calcolo le curve di intersezione con gli split CalcMixedIntersections( nPartId, nOutlineId, vCrvs) end ---------------------------------------------------------------------------------- --------------------------- PROFILING PROCESSINGS -------------------------------- ---------------------------------------------------------------------------------- -- funzione che copia sulla curva di lavorazione le informazioni prese dal semiprofilo corrispondente 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 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 CopyInfo( nCrv, nSemiProfile, WIN_PRC_PHASE) local nTools = EgtGetInfo( nSemiProfile, WIN_PRC_NTOOLS , 'i') or 0 EgtSetInfo( nCrv, WIN_PRC_NTOOLS, nTools) for j = 1, nTools do CopyInfo( nCrv, nSemiProfile, WIN_PRC_TOOL_NAME .. '_' .. tostring(j)) CopyInfo( nCrv, nSemiProfile, WIN_PRC_OFFL .. '_' .. tostring(j)) CopyInfo( nCrv, nSemiProfile, WIN_PRC_OFFR .. '_' .. tostring(j)) end else -- se non ha semiprofilo associato è un taglio EgtSetInfo( nCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.CUT) end end --------------------------------------------------------------------- -- funzione che calcola la prima lavorazione per l'innesto dello split sul telaio nel caso di cambio profilo local function CalcMixedFrameMilling1( nIntersCrv, nOutlineId, nMainProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId) local dOffs = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '1', 'd') local dDepth = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '1', 'd') local dFilletRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '1', 'd') -- primo tratto : taglio a 45° e fillet local nCrv1 = EgtCopyGlob( nIntersCrv, nProcLayerId) EgtExtendCurveStartByLen( nCrv1, 100) -- calcolo il tratto di outline local nCrv2 = EgtCopyGlob( nOutlineId, nProcLayerId) EgtOffsetCurve( nCrv2, - dOffs) if bSashFill then EgtInvertCurve( nCrv2) end local dParS = EgtCurveParamAtPoint( nCrv2, EgtEP( nCrv1)) local ptEnd = EgtIP( nCrv2, nSplitRef, ORIG()) local dParE = EgtCurveParamAtPoint( nCrv2, ptEnd) EgtTrimCurveStartEndAtParam( nCrv2, dParS, dParE) -- tratto di uscita a 45° local vtDir2 = EgtEV( nCrv2) vtDir2:rotate( Z_AX(), EgtIf( bSashFill, - 45, 45)) local nCrv3 = EgtLinePVL( nProcLayerId, ptEnd, vtDir2, 100) -- creo fillet local nFillet = EgtCurveFillet( nProcLayerId, nCrv2, EgtUP( nCrv2, 0.9), nCrv3, EgtUP( nCrv3, 0.1), dFilletRad, true) -- creo curva di lavorazione local nMillingCrv = EgtCurveCompo( nProcLayerId, {nCrv1, nCrv2, nFillet, nCrv3}) if bSashFill then EgtInvertCurve( nMillingCrv) end EgtModifyCurveThickness( nMillingCrv, - dDepth) -- setto info di lavorazione EgtSetInfo( nMillingCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) EgtSetInfo( nMillingCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) EgtSetInfo( nMillingCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN) EgtTrimCurveWithRegion( nMillingCrv, nSurfGeoId, true, false) end --------------------------------------------------------------------- -- funzione che calcola la seconda lavorazione per l'innesto dello split sul telaio nel caso di cambio profilo local function CalcMixedFrameMilling2( nIntersCrv, nOutlineId, nMainProfileId, nSplitProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId) local dOffs = EgtGetInfo( nMainProfileId, WIN_SASH_REF .. '2', 'd') local dDepth = EgtGetInfo( nMainProfileId, WIN_SASH_DEPTH .. '2', 'd') local dFilletRad = EgtGetInfo( nMainProfileId, WIN_RAD_REF .. '2', 'd') local dExtraDist = EgtGetInfo( nMainProfileId, WIN_EXTRA_DIST, 'd') local nCrv1 = EgtCopyGlob( nIntersCrv, nProcLayerId) EgtExtendCurveStartByLen( nCrv1, 100) -- calcolo il primo tratto di outline local nCrv2 = EgtCopyGlob( nOutlineId, nProcLayerId) EgtOffsetCurve( nCrv2, - dOffs + dExtraDist) if bSashFill then EgtInvertCurve( nCrv2) end -- taglio i due tratti per unirli local pt1 = EgtIP( nCrv1, nCrv2, ORIG()) local dParE1 = EgtCurveParamAtPoint( nCrv1, pt1) EgtTrimCurveEndAtParam( nCrv1, dParE1) local dParS2 = EgtCurveParamAtPoint( nCrv2, pt1) EgtTrimCurveStartAtParam( nCrv2, dParS2) -- calcolo fillet local nFillet1 = EgtCurveFillet( nProcLayerId, nCrv1, EgtUP( nCrv1, 0.9), nCrv2, EgtUP( nCrv2, 0.1), dFilletRad, true) -- calcolo il secondo tratto di outline local nCrv3 = EgtCopyGlob( nOutlineId, nProcLayerId) EgtOffsetCurve( nCrv3, - dOffs) if bSashFill then EgtInvertCurve( nCrv3) end local nSplitRef2 = EgtCopyGlob( nSplitRef, nProcLayerId) local dOffs1 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '1', 'd') local dOffs2 = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd') EgtOffsetCurve( nSplitRef2, dOffs2 - dOffs1) local pt2 = EgtIP( nCrv3, nSplitRef2, ORIG()) local pt3 = EgtIP( nCrv3, nSplitRef, ORIG()) local dParS3 = EgtCurveParamAtPoint( nCrv3, pt2) local dParE3 = EgtCurveParamAtPoint( nCrv3, pt3) EgtTrimCurveStartEndAtParam( nCrv3, dParS3, dParE3) EgtErase( nSplitRef2) -- calcolo il raccordo tra i due tratti di outline : è arco di raggio dFilletRad, tangente a nCrv2 e con punto finale pt2 -- calcolo il centro dell'arco local nCircleTmp = EgtCircle( nProcLayerId, pt2, dFilletRad) local nCrvTmp = EgtCopyGlob( nOutlineId, nProcLayerId) EgtOffsetCurve( nCrvTmp, - dOffs + dExtraDist - dFilletRad) local ptC = EgtIP( nCircleTmp, nCrvTmp, EgtIf( bSashFill, EgtEP( nCrvTmp), EgtSP( nCrvTmp))) EgtErase( {nCircleTmp, nCrvTmp}) local nFillet2 = EgtArcC2PEx( nProcLayerId, ptC, EgtSP( nCrv2), GDB_PT.TG, nCrv2, pt2) -- taglio il primo tratto di outline per collegarlo al raccordo local dParE2 = EgtCurveParamAtPoint( nCrv2, EgtSP( nFillet2)) EgtTrimCurveEndAtParam( nCrv2, dParE2) -- tratto di uscita a 45° local vtDir2 = EgtEV( nCrv3) vtDir2:rotate( Z_AX(), EgtIf( bSashFill, - 45, 45)) local nCrv4 = EgtLinePVL( nProcLayerId, EgtEP( nCrv3), vtDir2, 100) -- creo fillet local nFillet3 = EgtCurveFillet( nProcLayerId, nCrv3, EgtUP( nCrv3, 0.9), nCrv4, EgtUP( nCrv4, 0.1), dFilletRad, true) or GDB_ID.NULL -- creo curva di lavorazione local nMillingCrv = EgtCurveCompo( nProcLayerId, {nCrv1, nFillet1, nCrv2, nFillet2, nCrv3, nFillet3, nCrv4}) if bSashFill then EgtInvertCurve( nMillingCrv) end EgtModifyCurveThickness( nMillingCrv, - dDepth) -- setto info di lavorazione EgtSetInfo( nMillingCrv, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) EgtSetInfo( nMillingCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) EgtSetInfo( nMillingCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN) EgtTrimCurveWithRegion( nMillingCrv, nSurfGeoId, true, false) end --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profiling per un pezzo di telaio con cambio profilo local function CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeoId) -- a) lavorazioni profili -- per le lavorazioni dei profili out, left, right e in comune si usano le corrispondenti curve del geo local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) for i = 1, #vGeoCrvs do -- copio curva local nCrv = EgtCopyGlob( vGeoCrvs[i], nProcLayerId) -- recupero il semiprofilo associato local nSemiProfile = EgtGetInfo( nCrv, WIN_SEMI_PROFILE, 'i') GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile) end -- lavorazioni dei sottotratti in di sash e fill local nOutlinesGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_OUTLINES) local vCrvs = EgtGetAllInGroup( nOutlinesGrp) local b3Profile = GetProfileLocalBox( nMainProfileId) local dOffs = b3Profile:getMin():getX() for i = #vCrvs, 1, -1 do -- calcolo la curva di lavorazione local nCrv = EgtCopyGlob( vCrvs[i], nProcLayerId) EgtOffsetCurve( nCrv, dOffs) EgtInvertCurve( nCrv) nCrv = EgtTrimCurveWithRegion( nCrv, nSurfGeoId, true, true) -- setto le info di lavorazione dal semiprofilo local nSemiProfile = EgtGetFirstNameInGroup( nMainProfileId, EgtGetName( vCrvs[i]) .. WIN_IN) GetProcessingInfoFromSemiProfile( nCrv, nSemiProfile) -- sistemo info di lavorazione EgtSetInfo( nCrv, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.MIXED) EgtSetInfo( nCrv, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN) -- TO DO : calcolo di AddLen ? end -- b) lavorazioni sulle intersezioni con gli split local nIntersGrp = EgtGetFirstNameInGroup( nPartId, WIN_MIXED_INTERSECTIONS) local vInters = EgtGetAllInGroup( nIntersGrp) local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') for i = 1, #vInters do local bSashFill = ( EgtGetName( vCrvs[i]) == WIN_SASH) -- recupero lo split associato e creo la curva di riferimento per le fresature local nSplitId = EgtGetInfo( vCrvs[i], WIN_MIXED_SPLIT_REF, 'i') local nSplitProfileId = GetOutlineProfileId( nSplitId, false) local dRefSplit = EgtGetInfo( nSplitProfileId, WIN_SASH_REF .. '2', 'd') local nSplitRef = EgtCopyGlob( nSplitId, nProcLayerId) EgtOffsetCurve( nSplitRef, - dRefSplit) -- Fresatura 1 CalcMixedFrameMilling1( vInters[i], nOutlineId, nMainProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId) -- Fresatura 2 CalcMixedFrameMilling2( vInters[i], nOutlineId, nMainProfileId, nSplitProfileId, nSplitRef, bSashFill, nProcLayerId, nSurfGeoId) EgtErase( nSplitRef) end end --------------------------------------------------------------------- -- funzione che calcola le lavorazioni di profiling nel caso di uno split coinvolto da cambio profilo local function CalcMixedSplitProfilingProcessings( nSplitId, nProcLayerId, nGeoLayerId) -- a) lavorazione dei profili local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) for i = 1, #vGeoCrvs do -- copio la curva local nCrvId = EgtCopyGlob( vGeoCrvs[i], nProcLayerId) -- recupero il semiprofilo associato ( per left e right è stato salvato il profilo di tipo sash) local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i') -- setto le info dal semiprofilo GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId) end -- b) tagli a 45° -- left local nMixedLeft = EgtGetInfo( nSplitId, WIN_MIXED_REF_START, 'i') local nIntersLeft = EgtGetInfo( nMixedLeft, WIN_MIXED_INTERS_REF, 'i') local nMillingLeft = EgtCopyGlob( nIntersLeft, nProcLayerId) -- recupero profondità local vOutlineLeft = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi') local nProfileLeft = GetOutlineProfileId( vOutlineLeft[1], false) local dDepthLeft = EgtGetInfo( nProfileLeft, WIN_SASH_DEPTH .. '2', 'd') EgtModifyCurveThickness( nMillingLeft, - dDepthLeft) -- setto info di lavorazione EgtSetInfo( nMillingLeft, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) EgtSetInfo( nMillingLeft, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) EgtSetInfo( nMillingLeft, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.LEFT) -- right local nMixedRight = EgtGetInfo( nSplitId, WIN_MIXED_REF_END, 'i') local nIntersRight = EgtGetInfo( nMixedRight, WIN_MIXED_INTERS_REF, 'i') local nMillingRight = EgtCopyGlob( nIntersRight, nProcLayerId) -- recupero profondità local vOutlineRight = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi') local nProfileRight = GetOutlineProfileId( vOutlineRight[1], false) local dDepthRight = EgtGetInfo( nProfileRight, WIN_SASH_DEPTH .. '2', 'd') EgtModifyCurveThickness( nMillingRight, - dDepthRight) EgtInvertCurve( nMillingRight) -- setto info di lavorazione EgtSetInfo( nMillingRight, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) EgtSetInfo( nMillingRight, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) EgtSetInfo( nMillingRight, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.RIGHT) 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) -- recupero il geo e creo la superficie associata per limitare le lavorazioni local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local nSurfGeo = CreateGeoArea( nGeoLayerId, nProcLayerId) EgtSurfFrOffset( nSurfGeo, 50 * GEO.EPS_SMALL) -- recupero il gruppo dei profili local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) -- calcolo lavorazioni dei profili local bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false if bChangeProfile then -- 1) caso cambio profilo : telaio o split if EgtGetName( nOutlineId) == WIN_SPLIT then CalcMixedSplitProfilingProcessings( nOutlineId, nProcLayerId, nGeoLayerId) else CalcMixedFrameProfilingProcessings( nPartId, nProcLayerId, nGeoLayerId, nMainProfileId, nSurfGeo) end else -- 2) caso standard -- recupero tutte le curve del geo local vGeoCrvs = EgtGetAllInGroup( nGeoLayerId) for i = 1, #vGeoCrvs do -- copio curva local nCrvId = EgtCopyGlob( vGeoCrvs[i], nProcLayerId) -- recupero il semiprofilo associato local nSemiProfileId = EgtGetInfo( nCrvId, WIN_SEMI_PROFILE, 'i') -- setto le info dal semiprofilo GetProcessingInfoFromSemiProfile( nCrvId, nSemiProfileId) end end -- calcolo eventuali lavorazioni per strip local vStripDist = EgtGetInfo( nMainProfileId, WIN_STRIP_DIST, 'vi') or {} for i = 1, #vStripDist do local nStripCut = EgtCopyGlob( nOutlineId, nProcLayerId) EgtOffsetCurve( nStripCut, vStripDist[i]) -- modifico la curva in modo che sia a filo del geo EgtExtendCurveStartByLen( nStripCut, 1000) EgtExtendCurveEndByLen( nStripCut, 1000) nStripCut = EgtTrimCurveWithRegion( nStripCut, nSurfGeo, true, false) -- aggiusto orientamento per essere coerente con il geo corrispondente if vStripDist[i] < 0 then EgtInvertCurve( nStripCut) end -- setto info di lavorazione EgtSetName( nStripCut, WIN_PRC_TYPE.STRIP_CUT) EgtSetInfo( nStripCut, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.STRIP_CUT) end EgtErase( nSurfGeo) end ---------------------------------------------------------------------------------- ---------------------------------- SOLIDO ---------------------------------------- ---------------------------------------------------------------------------------- -- funzione che costruisce una superficie estrudendo il profilo sProfileName lungo l'outline local function CreateProfileSurf( nOutlineId, nProfileId, sProfileName, dExtraLen, nLayerId) -- creo guida con estensione in tangenza local nGuideId = EgtCopy( nOutlineId, nLayerId) if EgtGetType( nGuideId) == GDB_TY.CRV_LINE then EgtExtendCurveStartByLen( nGuideId, dExtraLen) EgtExtendCurveEndByLen( nGuideId, dExtraLen) else nGuideId = EgtCurveCompo( nLayerId, nGuideId) EgtAddCurveCompoLineTg( nGuideId, dExtraLen) EgtAddCurveCompoLineTg( nGuideId, dExtraLen, false) end -- verifico se necessaria inversione della guida nel caso sia curva "virtuale" ( ovvero in area null o split) che deriva da pezzo di split local nRefSplitId = EgtGetInfo( nOutlineId, WIN_REF_SPLIT, 'i') if nRefSplitId then -- recupero base outline per confrontarlo con lo split da cui deriva local nBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i') -- recupero vettore tangente nel punto medio del base outline local ptM = EgtMP( nBaseOutlineId) local vtM = EgtMV( nBaseOutlineId) -- recupero vettore tangente nello stesso punto della curva di split da cui deriva local dRefSplitPar = EgtCurveParamAtPoint( nRefSplitId, ptM) local vtMRefSplit = EgtUV( nRefSplitId, dRefSplitPar, -1) -- se i due vettori non sono orientati nella stessa direzione inverto la guida if not AreSameVectorApprox( vtM, vtMRefSplit) then EgtInvertCurve( nGuideId) end end -- recupero il profilo da estrudere local nOrigProfileId = EgtGetFirstNameInGroup( nProfileId, sProfileName) local nSectionId = EgtCopyGlob( nOrigProfileId, nLayerId) -- posiziono la sezione di estrusione sulla guida : -- recupero frame del profilo local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frProfile = EgtFR( nProfileFrameId, GDB_ID.ROOT) frProfile:invert() -- calcolo il frame di destinazione sulla guida local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId), GDB_RT.GLOB) -- posiziono con i riferimenti EgtTransform( nSectionId, frProfile, GDB_RT.GLOB) EgtTransform( nSectionId, frDest, GDB_RT.GLOB) -- creo la superfice di estrusione local nStmId = EgtSurfTmSwept( nLayerId, nSectionId, nGuideId, false, WIN_SURF_APPROX) EgtErase( nGuideId) EgtErase( nSectionId) return nStmId end --------------------------------------------------------------------- -- funzione che crea la superficie di trim per il solido local function CreateTrimSurf( nGeoId, nProfileId, dGeoWidth, nLayerId) -- recupero profilo di riferimento dalla curva geo local nOrigTrimProfileId = EgtGetInfo( nGeoId, WIN_SEMI_PROFILE, 'i') -- 1) minizinken if not nOrigTrimProfileId then local nGuideId = EgtCopy( nGeoId, nLayerId) EgtExtendCurveStartByLen( nGuideId, 4 * dGeoWidth) EgtExtendCurveEndByLen( nGuideId, 4 * dGeoWidth) EgtMove( nGuideId, Z_AX()) local b3Profile = GetProfileLocalBox( nProfileId) local nTrimSurf = EgtSurfTmByExtrusion( nLayerId, nGuideId, - Z_AX() * ( b3Profile:getDimY() + 2), WIN_SURF_APPROX) EgtInvertSurf( nTrimSurf) EgtErase( nGuideId) return nTrimSurf -- 2) controprofilo else -- recupero il controprofilo da estrudere local sTrimProfileName = EgtGetName( nOrigTrimProfileId) sTrimProfileName = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. sTrimProfileName -- recupero la curva di outline associata alla curva di geo local nRefOutline = EgtGetInfo( nGeoId, WIN_REF_OUTLINE, 'i') -- calcolo la superficie di estrusione return CreateProfileSurf( nRefOutline, nProfileId, sTrimProfileName, 4 * dGeoWidth, nLayerId) end end --------------------------------------------------------------------- -- funzione che crea le superfici di trim per uno split coinvolto da cambio profilo ( controprofilo della parte sash del telaio e taglio a 45°) local function CreateMixedSplitTrimSurf( nMixedOutlineId, nProfileId, dExtraLen, nLayerId) -- estrudo il controprofilo di tipo sash local nPartId = EgtGetParent( EgtGetParent( nMixedOutlineId)) local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') local sTrimProfile = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_OFST .. WIN_SASH .. WIN_CTRIN local nTrimStmId = CreateProfileSurf( nOutlineId, nProfileId, sTrimProfile, dExtraLen, nLayerId) -- creo il solido da intersecare con il controprofilo per il taglio a 45° local nIntersCrvId = EgtGetInfo( nMixedOutlineId, WIN_MIXED_INTERS_REF, 'i') local nGuideId = EgtCopyGlob( nIntersCrvId, nLayerId) local bSashFill = ( EgtGetName( nMixedOutlineId) ~= WIN_SASH) local vtDirH = EgtSV( nGuideId) vtDirH:rotate( Z_AX(), EgtIf( bSashFill, -135, 135)) local vtDirV = EgtSV( nGuideId) vtDirV:rotate( Z_AX(), EgtIf( bSashFill, -45, 45)) EgtAddCurveCompoLine( nGuideId, EgtEP( nGuideId) + dExtraLen * vtDirV) EgtAddCurveCompoLine( nGuideId, EgtSP( nGuideId) + dExtraLen * vtDirH, false) EgtAddCurveCompoLine( nGuideId, EgtSP( nGuideId) + dExtraLen * vtDirV, false) EgtCloseCurveCompo( nGuideId) EgtMove( nGuideId, 0.01 * Z_AX()) if bSashFill then EgtInvertCurve( nGuideId) end local dDepth = EgtGetInfo( nProfileId, WIN_SASH_DEPTH .. '2', 'd') local nCutStmId = EgtSurfTmByRegionExtrusion( nLayerId, nGuideId, - ( dDepth + 2) * Z_AX()) -- creo una superficie di trim unica EgtSurfTmSubtract( nTrimStmId, nCutStmId) EgtErase( { nGuideId, nCutStmId}) return nTrimStmId end --------------------------------------------------------------------- -- funzione che crea il solido di estrusione principale local function CreateMainSurf( nOutlineId, dExtraLen, nProfileId, sSectionName, nLayerId) -- curva guida local nGuideId = EgtCopy( nOutlineId, nLayerId) EgtSetName( nGuideId, WIN_MAINGUIDE) EgtSetStatus( nGuideId, GDB_ST.OFF) EgtExtendCurveStartByLen( nGuideId, dExtraLen) EgtExtendCurveEndByLen( nGuideId, dExtraLen) -- posiziono il profilo sulla curva guida : -- recupero il frame del profilo local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frInvert = EgtFR( nProfileFrameId) frInvert:invert() -- lo applico a tutte le geometrie del profilo EgtTransform( EgtGetAllInGroup( nProfileId), frInvert) -- assegno come riferimento del profilo il punto start dell'outline EgtChangeGroupFrame( nProfileId, Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId))) -- recupero outline del profilo Main e lo estrudo local nSectionId = EgtGetFirstNameInGroup( nProfileId, sSectionName) local nMainExtrusionId = EgtSurfTmSwept( nLayerId, nSectionId, nGuideId, false, WIN_SURF_APPROX) EgtSetName( nMainExtrusionId, WIN_SRF_MAIN) return nMainExtrusionId end --------------------------------------------------------------------- -- funzione che crea il solido di un pezzo di telaio con cambio profilo local function CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth) -- a) SOLIDO PRINCIPALE local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) -- creo i solidi corrispondenti ai diversi sottotratti uniformi del pezzo local nMixedOutlinesGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_OUTLINES) local vMixedOutlines = EgtGetAllInGroup( nMixedOutlinesGrp) local vMainExtrusions = {} for i = 1, #vMixedOutlines do local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. EgtGetName( vMixedOutlines[i]) .. WIN_SECTION local nMainExtrusionId = CreateMainSurf( vMixedOutlines[i], 2 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId) table.insert( vMainExtrusions, nMainExtrusionId) end -- taglio i sottopezzi nei punti di intersezione per unirli local nMixedIntersectionsGrp = EgtGetFirstNameInGroup( EgtGetParent( nSolidLayerId), WIN_MIXED_INTERSECTIONS) local vIntersections = EgtGetAllInGroup( nMixedIntersectionsGrp) for i = 1, #vIntersections do -- creo la superficie di separazione tra i due sottopezzi local bSashFill = ( EgtGetName( vMixedOutlines[i]) == WIN_SASH) local vtDirS = EgtSV( vIntersections[i]) vtDirS:rotate( Z_AX(), EgtIf( bSashFill, -135, 135)) local vtDirE = EgtSV( vIntersections[i]) vtDirE:rotate( Z_AX(), EgtIf( bSashFill, 45, -45)) local nCrvTrim = EgtCurveCompo( nSolidLayerId, vIntersections[i], false) EgtAddCurveCompoLine( nCrvTrim, EgtSP( nCrvTrim) + dGeoWidth * vtDirS, false) EgtAddCurveCompoLine( nCrvTrim, EgtEP( nCrvTrim) + dGeoWidth * vtDirE) EgtMove( nCrvTrim, Z_AX()) local nStmTrim = EgtSurfTmByExtrusion( nSolidLayerId, nCrvTrim, - 2 * dGeoWidth * Z_AX()) -- taglio i due sottopezzi EgtSurfTmSubtract( vMainExtrusions[i+1], nStmTrim) EgtInvertSurf( nStmTrim) EgtSurfTmSubtract( vMainExtrusions[i], nStmTrim) EgtErase( nCrvTrim) EgtErase( nStmTrim) end -- unisco i sottopezzi in una sola superficie for i = 2, #vMainExtrusions do EgtSurfTmAdd( vMainExtrusions[1], vMainExtrusions[i]) EgtErase( vMainExtrusions[i]) end -- creo una copia dell'estrusione principale ( usata per ferramenta) local nOrigMainExtrusionId = EgtCopy( vMainExtrusions[1], nSolidLayerId) EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN) EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF) -- come guida tengo solo una copia della curva di outline local vMainGuideIds = EgtGetNameInGroup( nSolidLayerId, WIN_MAINGUIDE) EgtErase( vMainGuideIds) local nMainGuideId = EgtCopyGlob( nOutlineId, nSolidLayerId) EgtSetName( nMainGuideId, WIN_MAINGUIDE) EgtSetStatus( nMainGuideId, GDB_ST.OFF) -- b) TRIM START local nPrevGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_LEFT) local nStartProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START) local nTrimSurfStart = CreateTrimSurf( nPrevGeoId, nStartProfileId, dGeoWidth, nSolidLayerId) EgtSetName( nTrimSurfStart, WIN_SRF_START) EgtSetStatus( nTrimSurfStart, GDB_ST.OFF) EgtSurfTmIntersect( vMainExtrusions[1], nTrimSurfStart) -- c) TRIM END local nNextGeoId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) local nEndProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END) local nTrimSurfEnd = CreateTrimSurf( nNextGeoId, nEndProfileId, dGeoWidth, nSolidLayerId) EgtSetName( nTrimSurfEnd, WIN_SRF_END) EgtSetStatus( nTrimSurfEnd, GDB_ST.OFF) EgtSurfTmIntersect( vMainExtrusions[1], nTrimSurfEnd) end --------------------------------------------------------------------- -- funzione che crea il solido di un pezzo di split coinvolto da cambio profilo local function CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, dGeoWidth) -- a) creo il solido di estrusione principale local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION local nMainExtrusionId = CreateMainSurf( nOutlineId, 2 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId) -- creo una copia local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId) EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN) EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF) -- b) trim start local nPrevProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_START) local nPrevMixedOutline = EgtGetInfo( nOutlineId, WIN_MIXED_REF_START, 'i') local nStmTrimStart = CreateMixedSplitTrimSurf( nPrevMixedOutline, nPrevProfileId, dGeoWidth, nSolidLayerId) EgtSetName( nStmTrimStart, WIN_SRF_START) EgtSetStatus( nStmTrimStart, GDB_ST.OFF) EgtSurfTmIntersect( nMainExtrusionId, nStmTrimStart) -- c) trim end local nNextProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_END) local nNextMixedOutline = EgtGetInfo( nOutlineId, WIN_MIXED_REF_END, 'i') local nStmTrimEnd = CreateMixedSplitTrimSurf( nNextMixedOutline, nNextProfileId, dGeoWidth, nSolidLayerId) EgtSetName( nStmTrimEnd, WIN_SRF_END) EgtSetStatus( nStmTrimEnd, GDB_ST.OFF) EgtSurfTmIntersect( nMainExtrusionId, nStmTrimEnd) end --------------------------------------------------------------------- -- funzione che crea il solido del pezzo local function CalcSolid( nPartId, nOutlineId) -- creo layer per solido local nSolidLayerId = EgtGroup( nPartId) EgtSetName( nSolidLayerId, WIN_SOLID) -- recupero profilo principale local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) -- recupero geo e la sua larghezza local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local dGeoWidth = EgtGetInfo( nGeoLayerId, WIN_GEOWIDTH, 'd') -- gestione speciale per pezzi con CAMBIO PROFILO local bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false if bChangeProfile then if EgtGetName( nOutlineId) == WIN_SPLIT then return CalcMixedSplitSolid( nOutlineId, nSolidLayerId, nProfileLayerId, dGeoWidth) else return CalcMixedFrameSolid( nOutlineId, nSolidLayerId, nProfileLayerId, nGeoLayerId, dGeoWidth) end end -- a) creo il solido di estrusione principale local nMainProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) local sSection = EgtIf( s_bSimplSolid, WIN_SIMPLIFIED, '') .. WIN_SECTION local nMainExtrusionId = CreateMainSurf( nOutlineId, 2 * dGeoWidth, nMainProfileId, sSection, nSolidLayerId) -- creo una copia ( usata per calcolo ferramenta) local nOrigMainExtrusionId = EgtCopy( nMainExtrusionId, nSolidLayerId) EgtSetName( nOrigMainExtrusionId, WIN_SRF_ORIGMAIN) EgtSetStatus( nOrigMainExtrusionId, GDB_ST.OFF) -- b) trim con i controprofili sullo start local vPrevGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) local vStartProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_START) for i = 1, #vPrevGeoId do -- creo la superficie di trim local nTrimSurf = CreateTrimSurf( vPrevGeoId[i], vStartProfileId[i], dGeoWidth, nSolidLayerId) EgtSetStatus( nTrimSurf, GDB_ST.OFF) EgtSetName( nTrimSurf, WIN_SRF_START) -- eseguo intersezione per ottenere un solido unico ( tagliare le due superfici con EgtSurfTmCut e poi unirle potrebbe creare piccoli buchi legati alle diverse approssimazioni) EgtSurfTmIntersect( nMainExtrusionId, nTrimSurf) end -- c) trim con i controprofili sull'end local vNextGeoId = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) local vEndProfileId = EgtGetNameInGroup( nProfileLayerId, WIN_PRF_END) for i = 1, #vNextGeoId do -- creo la superficie di trim local nTrimSurf = CreateTrimSurf( vNextGeoId[i], vEndProfileId[i], dGeoWidth, nSolidLayerId) EgtSetStatus( nTrimSurf, GDB_ST.OFF) EgtSetName( nTrimSurf, WIN_SRF_END) -- eseguo intersezione per ottenere un solido unico EgtSurfTmIntersect( nMainExtrusionId, nTrimSurf) end end --------------------------------------------------------------------- -- funzione che crea il solido del Fill local function CalcFillSolid( nPartId, nOutlineLayerId, nGeoLayerId) -- creo layer per solido local nSolidLayerId = EgtGroup( nPartId) EgtSetName( nSolidLayerId, WIN_SOLID) -- creo compo di outline local vOutlineList = EgtGetAllInGroup( nOutlineLayerId) local nCompoOutlineId = EgtCurveCompoByChain( nSolidLayerId, vOutlineList, EgtSP( vOutlineList[1]), false) -- recupero spessore vetro local dGlassThickness = EgtGetInfo( nGeoLayerId, WIN_GEOWIDTH, 'd') local nSurfId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nCompoOutlineId, Z_AX() * dGlassThickness) EgtErase( nCompoOutlineId) end ---------------------------------------------------------------------------------- ---------------------------------- DOWELS ---------------------------------------- ---------------------------------------------------------------------------------- -- funzione che sottrae il dowel al solido local function UpdateSolidWithDowel( nDowelId, nSolidId, vtDir, dLen, nLayerId) -- creo il solido del dowel a partire dalla circonferenza che lo definisce local nDowelSolidId if s_bSimplSolid then -- se solidi semplificati creo foro grossolano per velocizzare operazioni di subtract local nDowelApprox = EgtCopyGlob( nDowelId, nLayerId) EgtApproxCurve( nDowelApprox, GDB_CA.LINES, 0.2) nDowelSolidId = EgtSurfTmByRegionExtrusion( nLayerId, nDowelApprox, vtDir * dLen) EgtErase( nDowelApprox) else nDowelSolidId = EgtSurfTmByRegionExtrusion( nLayerId, nDowelId, vtDir * dLen) end -- sottraggo il dowel al solido EgtSurfTmSubtract( nSolidId, nDowelSolidId) EgtErase( nDowelSolidId) end --------------------------------------------------------------------- -- funzione che calcola il riferimento dove posizionare i dowels local function CreateDowelFrameDest( nRefProfileType, nPrevGeo, nGeo, nRefOutline, bFullOrShort, bSashOrFrame) -- 1) la direzione z è quella del pezzo short nel caso rettangolare local vtZ if nRefProfileType == WIN_PRF.TOP then vtZ = - X_AX() elseif nRefProfileType == WIN_PRF.BOTTOM or nRefProfileType == WIN_PRF.BOTTOMRAIL then vtZ = X_AX() elseif nRefProfileType == WIN_PRF.LEFT then vtZ = - Y_AX() elseif nRefProfileType == WIN_PRF.RIGHT then vtZ = Y_AX() end local frDest = Frame3d( ORIG(), - vtZ) -- 2) punto di origine local nPrevRight = EgtGetFirstNameInGroup( nPrevGeo, WIN_GEO_RIGHT) local ptRef1 = EgtIf( bFullOrShort, EgtSP( nPrevRight), EgtEP( nPrevRight)) local nLeft = EgtGetFirstNameInGroup( nGeo, WIN_GEO_LEFT) local ptRef2 = EgtIf( bFullOrShort, EgtSP( nLeft), EgtEP( nLeft)) -- riporto i punti sulla curva di outline su cui va posizionato il profilo con le spine local _, ptInt1 = EgtPointCurveDist( ptRef1, nRefOutline) local _, ptInt2 = EgtPointCurveDist( ptRef2, nRefOutline) -- nel caso di telaio conviene tenere il punto più "interno" visto che la correzione sarà fatta verso l'esterno -- nel caso di anta conviene tenere quello più "esterno" visto che la correzione sarà fatta verso l'interno ptInt1:toLoc( frDest) ptInt2:toLoc( frDest) local ptInt if ptInt1:getX() > ptInt2:getX() then ptInt = EgtIf( bSashOrFrame, Point3d( ptInt1), Point3d( ptInt2)) else ptInt = EgtIf( bSashOrFrame, Point3d( ptInt2), Point3d( ptInt1)) end ptInt:toGlob( frDest) -- modifico il punto di origine del frame nel punto individuato frDest:move( ptInt - ORIG()) return frDest end --------------------------------------------------------------------- -- funzione che posiziona il dowel tramite i riferimenti local function PositionDowel( nDowelId, frOrig, frDest, vtDir, nSurfId) -- posiziono il dowel utilizzando i riferimenti EgtTransform( nDowelId, frOrig, GDB_RT.GLOB) EgtTransform( nDowelId, frDest, GDB_RT.GLOB) EgtMove( nDowelId, 300 * vtDir) -- creo il tool corrispondente al dowel local dRad = EgtArcRadius( nDowelId) EgtCAvSetStdTool( s_dDowelTol, 2 * dRad, 0) -- calcolo spostamento per posizionarlo in corrispondenza della superficie local dStart = EgtCAvToolPosStm( EgtCP( nDowelId), - vtDir, nSurfId, - vtDir) EgtMove( nDowelId, - dStart * vtDir) end --------------------------------------------------------------------- -- funzione che crea il dowel e lo sottrae al solido local function CreateDowel( nOrigDowelId, nLayerId, frOrig, frDest, vtDir, nTestSurfId, sLenKey, sDowelSide, nMainExtrusionId) -- vtDir rivolta verso interno del pezzo local nDowelId = EgtCopyGlob( nOrigDowelId, nLayerId) EgtSetColor( nDowelId, Color3d( 128, 128, 128)) -- posiziono il dowel PositionDowel( nDowelId, frOrig, frDest, vtDir, nTestSurfId) -- assegno estrusione e spessore local dLen = EgtGetInfo( nOrigDowelId, sLenKey, 'd') + s_dDowelTol EgtModifyCurveExtrusion( nDowelId, - vtDir) EgtModifyCurveThickness( nDowelId, - dLen) -- setto info di lavorazione EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE) EgtSetInfo( nDowelId, WIN_PRC_SIDE, sDowelSide) -- eventuale aggiornamento del solido if nMainExtrusionId then UpdateSolidWithDowel( nDowelId, nMainExtrusionId, vtDir, dLen, nLayerId) end return nDowelId end --------------------------------------------------------------------- -- funzione che calcola la correzione da applicare al frame dei dowels per evitare che fuoriescano dal pezzo da un lato visibile ( esterno per ante ed interno per telaio) local function CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurfPos, nTestSurfPosPrev, nTestSurf, vtMove, nLayerId, sLenKey, sPrevLenKey) local dMove = 0 -- se le curve sono due linee ortogonali non serve correzione if EgtGetType( nOutlineId) == GDB_TY.CRV_LINE and EgtGetType( nPrevOutlineId) == GDB_TY.CRV_LINE then local vt1 = EgtSV( nPrevOutlineId) local vt2 = EgtSV( nOutlineId) local dAng = GetAngleXY( vt1, vt2) if abs( abs( dAng) - 90) < GEO.EPS_SMALL then return dMove end end -- 1) verifico posizione per il pezzo corrente -- posiziono il dowel local nDowel1 = EgtCopyGlob( nDowelRef, nLayerId) PositionDowel( nDowel1, frOrig, frDest, - frDest:getVersZ(), nTestSurfPos) -- verifico se la faccia di fondo fuoriesce dalla superficie di test local dLen = EgtGetInfo( nDowel1, sLenKey, 'd') + s_dDowelTol local dMove1 = EgtCAvToolPosStm( EgtCP( nDowel1) - frDest:getVersZ() * dLen, frDest:getVersZ(), nTestSurf, vtMove) -- 2) verifico posizione per il pezzo precedente -- posiziono il dowel local nDowel2 = EgtCopyGlob( nDowelRef, nLayerId) PositionDowel( nDowel2, frOrig, frDest, frDest:getVersZ(), nTestSurfPosPrev) -- verifico se la faccia di fondo fuoriesce dalla superficie di test local dPrevLen = EgtGetInfo( nDowel2, sPrevLenKey, 'd') + s_dDowelTol local dMove2 = EgtCAvToolPosStm( EgtCP( nDowel2) + frDest:getVersZ() * dPrevLen, - frDest:getVersZ(), nTestSurf, vtMove) EgtErase( nDowel1) EgtErase( nDowel2) -- calcolo la correzione complessiva dMove = max( dMove1, dMove2) return dMove end --------------------------------------------------------------------- -- funzione che calcola i dowels tra due pezzi local function CalcDowels( nOutlineId, nPrevOutlineId, bSashOrFrame, bBottomRail) -- recupero i pezzi local nPart = EgtGetInfo( nOutlineId, WIN_REF_PART, 'i') local nPrevPart = EgtGetInfo( nPrevOutlineId, WIN_REF_PART, 'i') if bBottomRail then if EgtGetName( nOutlineId) == WIN_BOTTOM then nPart = EgtGetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i') else nPrevPart = EgtGetInfo( nPrevOutlineId, WIN_REF_BOTTOMRAIL_PART, 'i') end end -- recupero i layer delle lavorazioni local nLayerId = EgtGetFirstNameInGroup( nPart, WIN_PRC) local nPrevLayerId = EgtGetFirstNameInGroup( nPrevPart, WIN_PRC) -- recupero i profili local nProfileLay = EgtGetFirstNameInGroup( nPart, WIN_PROFILE) local nProfileId = EgtGetFirstNameInGroup( nProfileLay, WIN_PRF_MAIN) local nPrevProfileLay = EgtGetFirstNameInGroup( nPrevPart, WIN_PROFILE) local nPrevProfileId = EgtGetFirstNameInGroup( nPrevProfileLay, WIN_PRF_MAIN) -- recupero i geo local nGeo = EgtGetFirstNameInGroup( nPart, WIN_GEO) local nPrevGeo = EgtGetFirstNameInGroup( nPrevPart, WIN_GEO) -- recupero i tipi di profilo local nPrevProfileType = GetOutlineProfileType( nPrevOutlineId, bBottomRail) local nProfileType = GetOutlineProfileType( nOutlineId, bBottomRail) -- caso particolare del triangolo : se lato top contro bottom il top deve essere gestito come un left/right if nProfileType == WIN_PRF.TOP and nPrevProfileType == WIN_PRF.BOTTOM then nProfileType = WIN_PRF.RIGHT elseif nProfileType == WIN_PRF.BOTTOM and nPrevProfileType == WIN_PRF.TOP then nPrevProfileType = WIN_PRF.LEFT end -- recupero i solidi local nPrevSolidId, nSolidId, nPrevSolidLay, nSolidLay if s_bCalcSolid then nSolidLay = EgtGetFirstNameInGroup( nPart, WIN_SOLID) nSolidId = EgtGetFirstNameInGroup( nSolidLay, WIN_SRF_MAIN) nPrevSolidLay = EgtGetFirstNameInGroup( nPrevPart, WIN_SOLID) nPrevSolidId = EgtGetFirstNameInGroup( nPrevSolidLay, WIN_SRF_MAIN) end -- recupero il tipo di giunzione local nJointType = EgtGetInfo( nOutlineId, WIN_STARTJOINT, 'i') if bBottomRail then if EgtGetName( nOutlineId) == WIN_BOTTOM then nJointType = WIN_PART_JNT.SHORT else nJointType = WIN_PART_JNT.FULL end end if nJointType == WIN_PART_JNT.ANGLED then -- TO DO elseif nJointType == WIN_PART_JNT.FULL then -- calcolo il riferimento del profilo local nFrameProfile = EgtGetFirstNameInGroup( nPrevProfileId, WIN_SECTIONFRAME) local frOrig = EgtFR( nFrameProfile, GDB_ID.ROOT) frOrig:invert() -- calcolo il riferimento su cui posizionare i dowels local frDest = CreateDowelFrameDest( nPrevProfileType, nPrevGeo, nGeo, nPrevOutlineId, true, bSashOrFrame) -- recupero info con la lunghezza ( dipendono dal profilo del pezzo full) local sLenKey = EgtIf( nProfileType == WIN_PRF.BOTTOM, WIN_DWL_BOTTOM_PERP_LEN, WIN_DWL_TOP_PERP_LEN) local sPrevLenKey = EgtIf( nProfileType == WIN_PRF.BOTTOM, WIN_DWL_BOTTOM_PARA_LEN, WIN_DWL_TOP_PARA_LEN) -- 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( nOutlineId, nPrevOutlineId, nProfileId) -- controprofilo in del pezzo corrente nTestSurf = CreateProfileSurf( nOutlineId, nProfileId, sCtrIn, 100, nLayerId) else -- è la superficie che viene utilizzata per trimmare l'end del pezzo prev local nOrigSurf = EgtGetFirstNameInGroup( nPrevSolidLay, WIN_SRF_END) nTestSurf = EgtCopyGlob( nOrigSurf, nLayerId) end local nTestSurfInverted = EgtCopyGlob( nTestSurf, nLayerId) EgtInvertSurf( nTestSurfInverted) -- superficie test per la traslazione dei dowels local nTestSurf2 if bSashOrFrame then -- se anta la superficie da cui non fuoriuscire è quella esterna del pezzo short, ovvero la superficie usata per trimmare lo start del pezzo corrente if not s_bCalcSolid or s_bSimplSolid then nTestSurf2 = CreateProfileSurf( nPrevOutlineId, nPrevProfileId, WIN_OFST .. WIN_OUT, 100, nLayerId) else local nOrigSurf = EgtGetFirstNameInGroup( nSolidLay, WIN_SRF_START) nTestSurf2 = EgtCopyGlob( nOrigSurf, nLayerId) end EgtInvertSurf( nTestSurf2) else -- se telaio la superficie da cui non fuoriuscire è quella interna del pezzo short local sCtrIn2 = WIN_OFST .. GetProfileCtrIn( nPrevOutlineId, nOutlineId, nPrevProfileId) nTestSurf2 = CreateProfileSurf( nPrevOutlineId, nPrevProfileId, sCtrIn2, 100, nLayerId) end -- direzione per la traslazione dei dowels local vtMove = EgtIf( bSashOrFrame, - frDest:getVersX(), frDest:getVersX()) -- analizzo le singole file di dowels for k = 1, 3 do -- recupero i dowels della fila k-esima local vDowels = EgtGetNameInGroup( nPrevProfileId, WIN_DOWEL .. 'Row' .. tostring( k)) if not vDowels then break end -- recupero il dowel nella posizione più problematica ( per le ante è quello più esterno, per il telaio quello più interno) local nDowelRef = EgtIf( bSashOrFrame, vDowels[1], vDowels[#vDowels]) -- calcolo correzione da applicare al frame affinchè i dowels non fuoriescano da un lato visibile ( esterno per ante ed interno per telaio) local dMove = CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurfInverted, nTestSurf, nTestSurf2, vtMove, nLayerId, sLenKey, sPrevLenKey) local frDestDowel = Frame3d( frDest) frDestDowel:move( dMove * vtMove) for i = 1, #vDowels do -- dowels per pezzo corrente ( full) CreateDowel( vDowels[i], nLayerId, frOrig, frDestDowel, - frDestDowel:getVersZ(), nTestSurfInverted, sLenKey, WIN_PRC_SIDETYPE.IN, nSolidId) -- dowels per prezzo precedente ( short) CreateDowel( vDowels[i], nPrevLayerId, frOrig, frDestDowel, frDestDowel:getVersZ(), nTestSurf, sPrevLenKey, WIN_PRC_SIDETYPE.RIGHT, nPrevSolidId) end end EgtErase( nTestSurf) EgtErase( nTestSurfInverted) EgtErase( nTestSurf2) elseif nJointType == WIN_PART_JNT.SHORT then -- calcolo il riferimento del profilo local nFrameProfile = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frOrig = EgtFR( nFrameProfile, GDB_ID.ROOT) frOrig:invert() -- calcolo il riferimento su cui posizionare i dowels local frDest = CreateDowelFrameDest( nProfileType, nPrevGeo, nGeo, nOutlineId, false, bSashOrFrame) -- recupero info con la lunghezza ( dipendono dal profilo del pezzo full, quindi da prezzo prev) local sLenKey = WIN_DWL_TOP_PARA_LEN local sPrevLenKey = WIN_DWL_TOP_PERP_LEN if nPrevProfileType == WIN_PRF.BOTTOM then sLenKey = WIN_DWL_BOTTOM_PARA_LEN sPrevLenKey = WIN_DWL_BOTTOM_PERP_LEN elseif nPrevProfileType == WIN_PRF.BOTTOM_RAIL then sLenKey = WIN_DWL_BOTTOMRAIL_PARA_LEN sPrevLenKey = WIN_DWL_BOTTOMRAIL_PERP_LEN end -- superficie test per il posizionamento dei dowels -- è 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( nPrevOutlineId, nOutlineId, nPrevProfileId) -- controprofilo del pezzo full nTestSurf = CreateProfileSurf( nPrevOutlineId, nPrevProfileId, sCtrIn, 100, nLayerId) else local nOrigSurf = EgtGetFirstNameInGroup( nSolidLay, WIN_SRF_START) nTestSurf = EgtCopyGlob( nOrigSurf, nLayerId) end local nTestSurfInverted = EgtCopyGlob( nTestSurf, nLayerId) EgtInvertSurf( nTestSurfInverted) -- superficie test per la traslazione dei dowels local nTestSurf2 if bSashOrFrame then if not s_bCalcSolid or s_bSimplSolid then nTestSurf2 = CreateProfileSurf( nOutlineId, nProfileId, WIN_OFST .. WIN_OUT, 100, nLayerId) else local nOrigSurf = EgtGetFirstNameInGroup( nPrevSolidLay, WIN_SRF_END) nTestSurf2 = EgtCopyGlob( nOrigSurf, nLayerId) end EgtInvertSurf( nTestSurf2) else local sCtrIn2 = WIN_OFST .. GetProfileCtrIn( nOutlineId, nPrevOutlineId, nProfileId) -- controprofilo del pezzo short nTestSurf2 = CreateProfileSurf( nOutlineId, nProfileId, sCtrIn2, 100, nLayerId) end -- direzione per la traslazione dei dowels local vtMove = EgtIf( bSashOrFrame, - frDest:getVersX(), frDest:getVersX()) -- analizzo le singole file di dowels for k = 1, 3 do -- recupero i dowels sulla fila k-esima local vDowels = EgtGetNameInGroup( nProfileId, WIN_DOWEL .. 'Row' .. tostring(k)) if not vDowels then break end -- recupero il dowel nella posizione più problematica ( per le ante è quello più esterno, per il telaio quello più interno) local nDowelRef = EgtIf( bSashOrFrame, vDowels[1], vDowels[#vDowels]) -- calcolo correzione da applicare al frame affinchè i dowels non fuoriescano da un lato visibile ( esterno per ante ed interno per telaio) local dMove = CalcDowelFrameCorrection( nOutlineId, nPrevOutlineId, nDowelRef, frOrig, frDest, nTestSurf, nTestSurfInverted, nTestSurf2, vtMove, nLayerId, sLenKey, sPrevLenKey) local frDestDowel = Frame3d( frDest) frDestDowel:move( dMove * vtMove) for i = 1, #vDowels do -- dowels per pezzo corrente ( short) CreateDowel( vDowels[i], nLayerId, frOrig, frDestDowel, - frDestDowel:getVersZ(), nTestSurf, sLenKey, WIN_PRC_SIDETYPE.LEFT, nSolidId) -- dowels per prezzo precedente ( full) CreateDowel( vDowels[i], nPrevLayerId, frOrig, frDestDowel, frDestDowel:getVersZ(), nTestSurfInverted, sPrevLenKey, WIN_PRC_SIDETYPE.IN, nPrevSolidId) end end EgtErase( nTestSurf) EgtErase( nTestSurfInverted) EgtErase( nTestSurf2) end end --------------------------------------------------------------------- -- funzione che calcola i dowels tra uno split e i pezzi sui cui poggia local function CalcSplitDowels( nSplitId, vOutlines, bStartOrEnd) -- TO DO : da gestire incrocio dowels di tre pezzi -- recupero il pezzo dello split local nSplitPart = EgtGetInfo( nSplitId, WIN_REF_PART, 'i') -- recupero il profilo originale dello split e il suo frame local nSplitProfile = GetOutlineProfileId( nSplitId, false) local nSplitProfileFrameId = EgtGetFirstNameInGroup( nSplitProfile, WIN_SECTIONFRAME) local frOrig = EgtFR( nSplitProfileFrameId, GDB_ID.ROOT) frOrig:invert() -- recupero il gruppo delle lavorazioni local nSplitLayerId = EgtGetFirstNameInGroup( nSplitPart, WIN_PRC) -- recupero eventuale solido e superifici usate per il suo trim local nSplitSolidId, vTestSurf if s_bCalcSolid then local nSplitSolidLayerId = EgtGetFirstNameInGroup( nSplitPart, WIN_SOLID) nSplitSolidId = EgtGetFirstNameInGroup( nSplitSolidLayerId, WIN_SRF_MAIN) vTestSurf = EgtGetNameInGroup( nSplitSolidLayerId, EgtIf( bStartOrEnd, WIN_SRF_START, WIN_SRF_END)) end -- indviduo il lato su cui andranno i dowels local sSplitDowelSide = WIN_PRC_SIDETYPE.RIGHT if bStartOrEnd then sSplitDowelSide = WIN_PRC_SIDETYPE.LEFT end -- creo la superficie di test per verificare se dowel interno al pezzo local nSplitGeo = EgtGetFirstNameInGroup( nSplitPart, WIN_GEO) local nSplitSurf = CreateGeoArea( nSplitGeo, nSplitLayerId) local ptRef = EgtIf( bStartOrEnd, EgtSP( nSplitId), EgtEP( nSplitId)) for i = 1, #vOutlines do -- recupero il pezzo associato e il suo outline di riferimento local nPartId = FindAssociatedPart( vOutlines[i]) local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') local nProfileType = GetOutlineProfileType( nOutlineId, true) -- calcolo il frame di destinazione -- trovo intersezione dello split con lato In o Out del geo local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) local ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef) local sDowelSide = WIN_PRC_SIDETYPE.IN if not ptInters and nProfileType == WIN_PRF.SPLIT then nGeoCrvId = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) ptInters = EgtIP( nGeoCrvId, nSplitId, ptRef) sDowelSide = WIN_PRC_SIDETYPE.OUT end -- se non trovo intersezione passo al successivo if ptInters then -- TO DO : gestione split non lineare local frDest = Frame3d( ptInters, - EgtSV( nSplitId)) -- recupero il layer con le lavorazioni local nLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) -- nel layer dei profili del pezzo aggiungo il profilo dello split posizionato correttamente local nProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) local nSplitProfileCopyId = EgtCopy( nSplitProfile, nProfileLayerId) local sSplitProfileType = EgtGetName( nSplitProfile) EgtSetInfo( nSplitProfileCopyId, WIN_PRF_TYPE, sSplitProfileType) EgtSetName( nSplitProfileCopyId, WIN_PRF_SPLIT) -- posiziono il profilo sulla curva di split EgtTransform( EgtGetAllInGroup( nSplitProfileCopyId), frOrig, GDB_RT.GLOB) EgtChangeGroupFrame( nSplitProfileCopyId, frDest, GDB_RT.GLOB) -- recupero eventuale solido local nSolidId if s_bCalcSolid then local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) nSolidId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN) end -- recupero le chiavi delle lunghezze ( dipendono dal profilo del pezzo su cui poggia lo split) local sSplitLenKey = WIN_DWL_TOP_PARA_LEN local sLenKey = WIN_DWL_TOP_PERP_LEN if nProfileType == WIN_PRF.BOTTOM then sSplitLenKey = WIN_DWL_BOTTOM_PARA_LEN sLenKey = WIN_DWL_BOTTOM_PERP_LEN elseif nProfileType == WIN_PRF.BOTTOMRAIL then sSplitLenKey = WIN_DWL_RAILBOTTOM_PARA_LEN sLenKey = WIN_DWL_RAILBOTTOM_PERP_LEN elseif nProfileType == WIN_PRF.SPLIT then sSplitLenKey = WIN_DWL_SPLIT_PARA_LEN sLenKey = WIN_DWL_SPLIT_PERP_LEN end -- creo la superficie di test per il posizionamento dei dowels local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) local nTestSurf if not s_bCalcSolid or s_bSimplSolid then local bChangeProfile = EgtGetInfo( nSplitId, WIN_PRF_CHANGE, 'b') or false if bChangeProfile then local nMixedOutline = EgtGetInfo( nSplitId, EgtIf( bStartOrEnd, WIN_MIXED_REF_START, WIN_MIXED_REF_END), 'i') nTestSurf = CreateMixedSplitTrimSurf( nMixedOutline, nProfileId, 100, nLayerId) else local sCtr = WIN_OFST .. GetProfileCtrIn( nOutlineId, nSplitId, nProfileId) nTestSurf = CreateProfileSurf( nOutlineId, nProfileId, sCtr, 100, nLayerId) end else -- è la stessa superficie utilizzata per il trim del solido nTestSurf = EgtCopyGlob( vTestSurf[i], nSplitLayerId) end local nTestSurfInverted = EgtCopyGlob( nTestSurf, nSplitLayerId) EgtInvertSurf( nTestSurfInverted) -- calcolo le direzioni entranti nei pezzi local vtSplitDir = EgtIf( bStartOrEnd, - frDest:getVersZ(), frDest:getVersZ()) local vtDir = frDest:getVersZ() local _, _, nSide = EgtPointCurveDistSide( ptInters + vtDir, nGeoCrvId, Z_AX()) if nSide == 1 then -- se a destra della curva significa che la direzione è uscente dal pezzo e va invertita vtDir = - vtDir end -- creo la superficie di test per verificare se dowel interno al pezzo local nGeo = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local nSurf = CreateGeoArea( nGeo, nLayerId) -- aggiungo i dowels local vDowels = EgtGetNameInGroup( nSplitProfile, WIN_DOWEL .. '*') or {} for i = 1, #vDowels do -- split local nDowel1 = CreateDowel( vDowels[i], nSplitLayerId, frOrig, frDest, vtSplitDir, nTestSurf, sSplitLenKey, sSplitDowelSide, nSplitSolidId) -- verifico se dowel è interno al pezzo ( TO DO : da migliorare!) local ptTest = EgtCP( nDowel1) - vtSplitDir * EgtCurveThickness( nDowel1) local nTestPoint = EgtPoint( nSplitLayerId, ptTest) if EgtSurfFrTestExternal( nSplitSurf, nTestPoint) then EgtErase( nDowel1) end EgtErase( nTestPoint) -- pezzo local nDowel2 = CreateDowel( vDowels[i], nLayerId, frOrig, frDest, vtDir, nTestSurfInverted, sLenKey, sDowelSide, nSolidId) ptTest = EgtCP( nDowel2) - vtDir * EgtCurveThickness( nDowel2) nTestPoint = EgtPoint( nLayerId, ptTest) if EgtSurfFrTestExternal( nSurf, nTestPoint) then EgtErase( nDowel2) end EgtErase( nTestPoint) end EgtErase( nTestSurf) EgtErase( nTestSurfInverted) EgtErase( nSurf) end end EgtErase( nSplitSurf) end --------------------------------------------------------------------- -- funzione che calcola le spine local function CalculateAreaDowels( nAreaId) local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then -- verifico se presente bottomrail local bBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'b') or false -- aggiungo le spine sui pezzi dell'area local nOutline = EgtGetFirstInGroup( nOutlineLayerId) local nPrevOutline = EgtGetLastInGroup( nOutlineLayerId) while nOutline do -- aggiungo spine su nOutline e nPrevOutline nel loro punto di giunzione CalcDowels( nOutline, nPrevOutline, nAreaType == WIN_AREATYPES.SASH, false) -- bottomrail if bBottomRail and ( EgtGetName( nOutline) == WIN_BOTTOM or EgtGetName( nPrevOutline) == WIN_BOTTOM) then CalcDowels( nOutline, nPrevOutline, false, true) end -- aggiorno per iterazione successiva nPrevOutline = nOutline nOutline = EgtGetNext( nOutline) end end -- verifico se c'e' uno split local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) if nSplitLayerId then local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL -- se split non è di tipo french ha un pezzo associato per il quale vanno calcolate le spine if nSplitType ~= WIN_SPLITTYPES.FRENCH then local nSplitId = EgtGetFirstInGroup( nSplitLayerId) -- start local vPrevOutlineId = EgtGetInfo( nSplitId, WIN_PREV_OUTLINES, 'vi') CalcSplitDowels( nSplitId, vPrevOutlineId, true) -- end local vNextOutlineId = EgtGetInfo( nSplitId, WIN_NEXT_OUTLINES, 'vi') CalcSplitDowels( nSplitId, vNextOutlineId, false) end end -- calcolo le spine delle sottoaree local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') while nChildAreaId do CalculateAreaDowels( nChildAreaId) nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') end end ---------------------------------------------------------------------------------- --------------------------------- STRIP ---------------------------------------- ---------------------------------------------------------------------------------- -- funzione che restitutisce lo Strip piu' vicino -- ( analoga a GetProfileCtrIn) local function GetStripNearestToOutline( nPrevProfileId, nPrevOutlineId, nOutlineId) local sStripName = WIN_STRIP -- gestione particolare del caso di profilo di split if not EgtGetFirstNameInGroup( nPrevProfileId, sStripName) then -- recupero la curva di base outline da cui deriva il precedente local nPrevSouId = EgtGetInfo( nPrevOutlineId, WIN_COPY, 'i') local sPrevSouName repeat nPrevSouId = EgtGetInfo( nPrevSouId, WIN_SOU, 'i') sPrevSouName = EgtGetName( nPrevSouId or GDB_ID.NULL) until not nPrevSouId or sPrevSouName == WIN_SPLIT -- verifico da quale lato si trova la curva per decidere quale controprofilo considerare local _, _, nSide = EgtPointCurveDistSide( EgtMP( nOutlineId), nPrevSouId, Z_AX()) if nSide == 1 then sStripName = WIN_STRIP .. '1' -- dx else sStripName = WIN_STRIP .. '2' -- sx end end if s_bSimplSolid then sStripName = WIN_SIMPLIFIED .. sStripName end local nStripId = EgtGetFirstNameInGroup( nPrevProfileId, sStripName) return nStripId end --------------------------------------------------------------------- -- funzione che crea le linee di contorno massima e minima degli strip local function CreateStripGuideLines( nOutlineId, nStripId, nProfileId, nSolidLayerId) -- recupero il frame del profilo local nProfileFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frProfile = EgtFR( nProfileFrameId, GDB_ID.ROOT) -- se profilo e direzione prev uguali ( Prev e' Split), cambio segno all'offset di modo che rimanga sempre dalla stessa parte local vtE = EgtEV( nOutlineId) local bMainInvertOffset = AreSameVectorApprox( frProfile:getVersZ(), vtE) -- calcolo BBox local b3MainStrip = EgtGetBBoxRef( nStripId, GDB_BB.STANDARD, frProfile, GDB_RT.GLOB) -- calcolo offset per Strip local dMainStripMinDelta = EgtIf( bMainInvertOffset, - b3MainStrip:getMax():getX(), b3MainStrip:getMin():getX()) local dMainStripMaxDelta = EgtIf( bMainInvertOffset, - b3MainStrip:getMin():getX(), b3MainStrip:getMax():getX()) local nStripMinOffsetId = EgtCopy( nOutlineId, nSolidLayerId) EgtOffsetCurve( nStripMinOffsetId, dMainStripMinDelta) local nStripMaxOffsetId = EgtCopy( nOutlineId, nSolidLayerId) EgtOffsetCurve( nStripMaxOffsetId, dMainStripMaxDelta) return nStripMinOffsetId, nStripMaxOffsetId end --------------------------------------------------------------------- -- funzione che crea gli Strip local function CreateStripFromOutline( nAreaId, nOutlineId) -- recupero il pezzo associato ( prendendo quello di bottomrail se esiste) local nPartId = FindAssociatedPart( nOutlineId) -- recupero layer per solido e per profili di estrusione local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) -- recupero gli outline precedente e successivo ( non serve utilizzare un WIN_PRF accurato perchè conta solo sia diverso da split) local nOutlineLayerId = EgtGetParent( nOutlineId) local vPrevOutlineId, vNextOutlineId = GetPrevNextOutline( WIN_PRF.NULL, nOutlineId, nOutlineLayerId) -- recupero i pezzi precedente e successivo, prendendo eventualmente quelli di bottomrail local nPrevPartId = FindAssociatedPart( vPrevOutlineId[1]) local nNextPartId = FindAssociatedPart( vNextOutlineId[1]) -- recupero profilo e controprofili local nMainProfileLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PROFILE) local nMainProfileId = EgtGetFirstNameInGroup( nMainProfileLayerId, WIN_PRF_MAIN) local nPrevProfileLayerId = EgtGetFirstNameInGroup( nPrevPartId, WIN_PROFILE) local nStartProfileId = EgtGetFirstNameInGroup( nPrevProfileLayerId, WIN_PRF_MAIN) local nNextProfileLayerId = EgtGetFirstNameInGroup( nNextPartId, WIN_PROFILE) local nEndProfileId = EgtGetFirstNameInGroup( nNextProfileLayerId, WIN_PRF_MAIN) -- a) estrudo il fermavetro -- recupero guida Main local nGuideId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_MAINGUIDE) -- recupero strip piu' vicino a prev outline e lo posiziono sulla guida local nMainStripId = GetStripNearestToOutline( nMainProfileId, nOutlineId, vPrevOutlineId[1]) local nSectionId = EgtCopyGlob( nMainStripId, nSolidLayerId) local nFrameProfileId = EgtGetFirstNameInGroup( nMainProfileId, WIN_SECTIONFRAME) local frOrig = EgtFR( nFrameProfileId, GDB_ID.ROOT) frOrig:invert() local frDest = Frame3d( EgtSP( nGuideId), - EgtSV( nGuideId)) EgtTransform( nSectionId, frOrig) EgtTransform( nSectionId, frDest) -- creo estrusione local nMainStripExtrusionId = EgtSurfTmSwept( nSolidLayerId, nSectionId, nGuideId, false, WIN_SURF_APPROX) EgtSetName( nMainStripExtrusionId, WIN_SRF_STRIP) -- b) taglio con start -- recupero strip dello start piu' vicino ad outline local nStartStripId = GetStripNearestToOutline( nStartProfileId, vPrevOutlineId[1], nOutlineId) -- disegno guida start per lo strip trovando le intersezioni degli outline minimi e massimi tra MainStrip e StartStrip local nMainStripMinOffsetId, nMainStripMaxOffsetId = CreateStripGuideLines( nOutlineId, nMainStripId, nMainProfileId, nSolidLayerId) local nStartStripMinOffsetId, nStartStripMaxOffsetId = CreateStripGuideLines( vPrevOutlineId[1], nStartStripId, nStartProfileId, nSolidLayerId) local ptStripMinStart = FindIntersectionPoint( nMainStripMinOffsetId, nStartStripMinOffsetId, EgtSP( nMainStripMinOffsetId)) local ptStripMaxStart = FindIntersectionPoint( nMainStripMaxOffsetId, nStartStripMaxOffsetId, EgtSP( nMainStripMinOffsetId)) local nStartStripGuideId = EgtLine( nSolidLayerId, ptStripMinStart, ptStripMaxStart) EgtExtendCurveStartByLen( nStartStripGuideId, 10) EgtExtendCurveEndByLen( nStartStripGuideId, 10) EgtMove( nStartStripGuideId, Z_AX()) -- estrudo Strip start local b3RefStartProfile = GetProfileLocalBox( nStartProfileId) local nStartStripExtrusionId = EgtSurfTmByExtrusion( nSolidLayerId, nStartStripGuideId, - Z_AX() * ( b3RefStartProfile:getDimY() + 2), WIN_SURF_APPROX) EgtInvertSurf( nStartStripExtrusionId) -- intersezione con main EgtSurfTmIntersect( nMainStripExtrusionId, nStartStripExtrusionId) -- c) taglio con end -- recupero strip piu' vicino ad outline local nEndStripId = GetStripNearestToOutline( nEndProfileId, vNextOutlineId[1], nOutlineId) -- disegno guida end per lo strip trovando le intersezioni degli outline minimi e massimi tra MainStrip ed EndStrip local nEndStripMinOffsetId, nEndStripMaxOffsetId = CreateStripGuideLines( vNextOutlineId[1], nEndStripId, nEndProfileId, nSolidLayerId) local ptStripMinEnd = FindIntersectionPoint( nMainStripMinOffsetId, nEndStripMinOffsetId, EgtEP( nMainStripMinOffsetId)) local ptStripMaxEnd = FindIntersectionPoint( nMainStripMaxOffsetId, nEndStripMaxOffsetId, EgtEP( nMainStripMaxOffsetId)) local nEndStripGuideId = EgtLine( nSolidLayerId, ptStripMinEnd, ptStripMaxEnd) EgtExtendCurveStartByLen( nEndStripGuideId, 10) EgtExtendCurveEndByLen( nEndStripGuideId, 10) EgtMove( nEndStripGuideId, Z_AX()) -- estrudo Strip end local b3RefEndProfile = GetProfileLocalBox( nEndProfileId) local nEndStripExtrusionId = EgtSurfTmByExtrusion( nSolidLayerId, nEndStripGuideId, - Z_AX() * ( b3RefEndProfile:getDimY() + 2), WIN_SURF_APPROX) -- intersezione con main EgtSurfTmIntersect( nMainStripExtrusionId, nEndStripExtrusionId) -- cancello curve e superfici di costruzione EgtErase( nSectionId) EgtErase( { nMainStripMinOffsetId, nMainStripMaxOffsetId}) EgtErase( { nStartStripMinOffsetId, nStartStripMaxOffsetId, nStartStripGuideId, nStartStripExtrusionId}) EgtErase( { nEndStripMinOffsetId, nEndStripMaxOffsetId, nEndStripGuideId, nEndStripExtrusionId}) end ---------------------------------------------------------------------------------- ----------------------------- CALCOLO PEZZI ------------------------------------ ---------------------------------------------------------------------------------- -- funzione che calcola l'ingombro dei pezzi del telaio e i loro solidi local function CreatePartFromOutline( nAreaLayerId, nOutlineId, nOutlineCrvNbr, bBottomRail) -- creo pezzo local nPartId = EgtGroup( GDB_ID.ROOT) -- inserisco riferimento alla sua area EgtSetInfo( nPartId, WIN_AREA, nAreaLayerId) local nAreaType = EgtGetInfo( nAreaLayerId, WIN_AREATYPE, 'i') local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaLayerId, WIN_OUTLINE) -- a) Telaio, anta o split if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH or nAreaType == WIN_AREATYPES.SPLIT then -- creo riferimenti tra pezzo e outline EgtSetInfo( nPartId, WIN_REF_OUTLINE, nOutlineId) if bBottomRail then EgtSetInfo( nOutlineId, WIN_REF_BOTTOMRAIL_PART, nPartId) else EgtSetInfo( nOutlineId, WIN_REF_PART, nPartId) end -- imposto nome del pezzo local sName = EgtGetName( nOutlineId) if bBottomRail then sName = WIN_BOTTOMRAIL end EgtSetName( nPartId, sName) -- imposto colore if sName == WIN_BOTTOM or sName == WIN_TOP or bBottomRail then EgtSetColor( nPartId, Color3d( 204, 102, 0)) elseif sName == WIN_RIGHT or sName == WIN_LEFT then EgtSetColor( nPartId, Color3d( 251, 128, 4)) else EgtSetColor( nPartId, Color3d( 255, 159, 57)) end -- setto le info di sovramateriale ( TO DO : capire da dove devono essere ricavate) EgtSetInfo( nPartId, WIN_PRC_OVERMAT_IN, 0) EgtSetInfo( nPartId, WIN_PRC_OVERMAT_OUT, 0) EgtSetInfo( nPartId, WIN_PRC_OVERMAT_LEFT, 0) EgtSetInfo( nPartId, WIN_PRC_OVERMAT_RIGHT, 0) -- ricavo il tipo di profilo local nProfileType = GetOutlineProfileType( nOutlineId, bBottomRail) -- disegno ingombro CalcFrameGeo( nPartId, nOutlineId, nOutlineCrvNbr, nOutlineLayerId, nProfileType) -- calcolo eventuali curve ausiliarie per cambio profilo local bChangeProfile = EgtGetInfo( nOutlineId, WIN_PRF_CHANGE, 'b') or false if bChangeProfile and nProfileType ~= WIN_PRF.SPLIT then CalcMixedFrameCurves( nPartId, nOutlineId) end -- calcolo le lavorazioni associate ai profili CalcProfilingProcessings( nPartId, nOutlineId) -- disegno solido if s_bCalcSolid then CalcSolid( nPartId, nOutlineId) end -- b) Fill elseif nAreaType == WIN_AREATYPES.FILL then -- imposto nome del pezzo EgtSetName( nPartId, WIN_FILL) -- ricavo tipo local nFillType = EgtGetInfo( nAreaLayerId, WIN_FILLTYPE, 'i') -- imposto colore if nFillType == WIN_FILLTYPES.GLASS then EgtSetColor( nPartId, Color3d( 71, 161, 255)) EgtSetAlpha( nPartId, 30) elseif nFillType == WIN_FILLTYPES.WOOD then EgtSetColor( nPartId, Color3d( 194, 148, 103)) end -- disegno ingombro local nGeoLayerId = CalcFillGeo( nPartId, nOutlineLayerId) -- disegno solido if s_bCalcSolid then CalcFillSolid( nPartId, nOutlineLayerId, nGeoLayerId) end end return nPartId end --------------------------------------------------------------------- -- funzione che cicla ricorsivamente su aree e sottoaree per calcolare i pezzi local function CalculateAreaParts( nAreaId) local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') if nAreaType == WIN_AREATYPES.FRAME or nAreaType == WIN_AREATYPES.SASH then -- creo pezzi per ogni outline local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) local vOutlines = EgtGetAllInGroup( nOutlineLayerId) for i = 1, #vOutlines do -- creo pezzo CreatePartFromOutline( nAreaId, vOutlines[i], i) -- se di tipo bottom verifico se ha bottomrail local sName = EgtGetName( vOutlines[i]) if sName == WIN_BOTTOM then local bBottomRail = EgtGetInfo( nOutlineLayerId, WIN_BOTTOMRAIL, 'b') or false if bBottomRail then CreatePartFromOutline( nAreaId, vOutlines[i], i, true) end end end elseif nAreaType == WIN_AREATYPES.FILL then -- creo riempimento CreatePartFromOutline( nAreaId) end -- verifico se c'e' uno split da realizzare local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) if nSplitLayerId then local nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i') or WIN_SPLITTYPES.NULL -- se split non è di tipo french ha un pezzo associato if nSplitType ~= WIN_SPLITTYPES.FRENCH then local nSplitId = EgtGetFirstInGroup( nSplitLayerId) if nSplitId then -- creo pezzo split local nSplitPartId = CreatePartFromOutline( nAreaId, nSplitId) -- disegno area di selezione per programma local nSelectionLayerId = EgtGroup( nAreaId) EgtSetName( nSelectionLayerId, WIN_SPLITSELECTION) EgtSetStatus( nSelectionLayerId, GDB_ST.OFF) local nSplitPartGeoId = EgtGetFirstNameInGroup( nSplitPartId, WIN_GEO) local nSelectionArea = CreateGeoArea( nSplitPartGeoId, nSelectionLayerId) EgtSetColor( nSelectionArea, 'YELLOW') EgtSetAlpha( nSelectionArea, 10) EgtMove( nSelectionArea, 10 * Z_AX()) end end elseif nAreaType ~= WIN_AREATYPES.FILL then if s_bCalcSolid then --- verifico se area successiva e' un fill local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREAASTERISK) local nChildAreaType = EgtGetInfo( nChildAreaId or GDB_ID.NULL, WIN_AREATYPE, "i") if nChildAreaType == WIN_AREATYPES.FILL then -- se lo e', vuol dire che e' un vetro fisso, quindi calcolo strip dell'outline local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId) while nOutlineId do CreateStripFromOutline( nAreaId, nOutlineId) nOutlineId = EgtGetNext( nOutlineId) end end end end -- disegno area di selezione per programma local nSelectionLayerId = EgtGroup( nAreaId) EgtSetName( nSelectionLayerId, WIN_SELECTION) EgtSetStatus( nSelectionLayerId, GDB_ST.OFF) local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) local vOutlineList = EgtGetAllInGroup( nOutlineLayerId) local nCompoId = EgtCurveCompo( nSelectionLayerId, vOutlineList, false) local nSelectionArea = EgtSurfFlatRegion( nSelectionLayerId, nCompoId) EgtSetColor( nSelectionArea, 'YELLOW') EgtSetAlpha( nSelectionArea, 10) EgtMove( nSelectionArea, 10 * Z_AX()) EgtErase( nCompoId) -- calcolo i pezzi delle sottoaree local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') while nChildAreaId do CalculateAreaParts( nChildAreaId) nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') end end ---------------------------------------------------------------------------------- ---------------------------------- TRONCHETTI ---------------------------------- ---------------------------------------------------------------------------------- -- funzione che spezza l'anta in corrispondenza dei tronchetti del telaio local function SplitArcByAlignment( nGeoIn, nGrp) -- recupero il pezzo del telaio corrispondente local nPartId = EgtGetParent( EgtGetParent( nGeoIn)) local nOutlineId = EgtGetInfo( nPartId, WIN_REF_OUTLINE, 'i') local nSouId = EgtGetInfo( nOutlineId, WIN_COPY, 'i') local nAreaType = WIN_AREATYPES.NULL while nSouId and nAreaType ~= WIN_AREATYPES.FRAME do nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i') or GDB_ID.NULL local nParentArea = EgtGetParent( EgtGetParent( nSouId)) or GDB_ID.NULL nAreaType = EgtGetInfo( nParentArea, WIN_AREATYPE, 'i') end if not nSouId then return end local nFrameOutlineId = EgtGetInfo( nSouId, WIN_COPY, 'i') local nFramePartId = EgtGetInfo( nFrameOutlineId, WIN_REF_PART, 'i') -- recupero le parti in cui era stato diviso l'arco del telaio local nFrameLogsLayer = EgtGetFirstNameInGroup( nFramePartId, WIN_LOGS) local vFrameLogs = EgtGetNameInGroup( nFrameLogsLayer, WIN_GEO_IN) local ptC = EgtCP( vFrameLogs[1]) local nCurrCrvId = EgtCopyGlob( nGeoIn, nGrp) local bInters = false for i = 1, #vFrameLogs - 1 do -- ricavo il punto di split sull'arco dell'anta local ptFrame = EgtEP( vFrameLogs[i]) local vtDir = ptFrame - ptC local nLineSplit = EgtLinePVL( nGrp, ptC, vtDir, vtDir:len() + 1000) local ptInt = EgtIP( nCurrCrvId, nLineSplit, ORIG()) EgtErase( nLineSplit) if ptInt then nCurrCrvId = EgtSplitCurveAtPoint( nCurrCrvId, ptInt) or GDB_ID.NULL bInters = true elseif bInters then -- se non ci sono più intersezioni esco return end end end --------------------------------------------------------------------- -- funzione che spezza l'arco in base al numero di pezzi local function SplitArcByNumber( nLogsNbr, nGeoIn, nGrp) local nCopy = EgtCopyGlob( nGeoIn, nGrp) EgtSplitCurve( nCopy, nLogsNbr) end --------------------------------------------------------------------- -- funzione che spezza gli archi per i tronchetti local function SplitArc( nLogsNbr, vSections, bAlign, dOverMatTot, nGeoIn, nGeoOut, nGrp) -- per allineamento con telaio if bAlign then return SplitArcByAlignment( nGeoIn, nGrp) -- per sezione elseif #vSections == 1 and nLogsNbr == 0 then -- dalla sezione ricavo il numero minimo di pezzi local dSection = vSections[1] - dOverMatTot local dROut = EgtArcRadius( nGeoOut) local dRIn = EgtArcRadius( nGeoIn) local dAng = abs( EgtArcAngCenter( nGeoIn)) local nParts if dSection < dROut - dRIn + GEO.EPS_SMALL then -- sezione troppo piccola -- TO DO : gestione errore EgtOutBox( 'Sezione tronchetto troppo piccola', '') elseif dSection > dROut + dRIn - GEO.EPS_SMALL then -- la sezione comprende già l'intero pezzo nParts = 1 else nParts = dAng / 2 / acos( ( dROut - dSection) / dRIn) nParts = ceil( nParts) end return SplitArcByNumber( nParts, nGeoIn, nGrp) -- per numero di pezzi else return SplitArcByNumber( nLogsNbr, nGeoIn, nGrp) end end --------------------------------------------------------------------- -- funzione che calcola la sezione dei tronchetti local function CalcLogsSection( nLogsNbr, vSections, bAlign, dOverMatTot, nGeoIn, nGeoOut, nGrp) -- se richiesta una sezione specifica senza vincoli sul numero di pezzi if not bAlign and #vSections == 1 and nLogsNbr == 0 then return vSections[1] end -- calcolo la sezione necessaria per la suddivisione scelta local dMySection = 0 local dROut = EgtArcRadius( nGeoOut) local dRIn = EgtArcRadius( nGeoIn) if bAlign then -- calcolo la massima sezione dai tronchetti ottenuti local vSplits = EgtGetAllInGroup( nGrp) for i = 1, #vSplits do local dAng = abs( EgtArcAngCenter( vSplits[i])) local dCurrSection = dROut - dRIn * cos( dAng / 2) if dCurrSection > dMySection then dMySection = dCurrSection end end dMySection = dMySection + dOverMatTot else -- ricavo la sezione dal numero di pezzi local dAng = abs( EgtArcAngCenter( nGeoIn)) dMySection = dROut - dRIn * cos( dAng / nLogsNbr / 2) + dOverMatTot end if #vSections == 0 then -- se no vincoli sulla sezione return dMySection else -- cerco la sezione più adatta dalla lista di sezioni disponibili table.sort( vSections) for i = 1, #vSections do if vSections[i] > dMySection - GEO.EPS_SMALL then return vSections[i] end end -- se non ho trovato la sezione errore EgtOutBox( 'Sezioni tronchetti troppo piccole per suddivisione richiesta', '') return nil end end --------------------------------------------------------------------- local function CalcLogs( nGrp, nGeoOut, dOverMatIn, dOverMatOut, dOverMatExt, dOverMatInt, dRefSection, bCutExtremities) -- recupero tutti i tratti dell'arco local vCrvsIn = EgtGetAllInGroup( nGrp) local ptC = EgtCP( vCrvsIn[1]) -- calcolo i tronchetti for i = 1, #vCrvsIn do local ptSIn = EgtSP( vCrvsIn[i]) local ptEIn = EgtEP( vCrvsIn[i]) -- recupero il tratto corrispondente sulla curva out local ptSOut, dParSOut, ptEOut, dParEOut if i == 1 then -- forzo a coincidere con l'estremo della curva out ptEOut = EgtEP( nGeoOut) dParEOut = 1 else _, ptEOut, dParEOut = EgtPointCurveDist( ptSIn, nGeoOut) end if i == #vCrvsIn then -- forzo a coincidere con l'estremo della curva out ptSOut = EgtSP( nGeoOut) dParSOut = 0 else _, ptSOut, dParSOut = EgtPointCurveDist( ptEIn, nGeoOut) end local nOut = EgtCopyGlob( nGeoOut, nGrp) EgtTrimCurveStartEndAtParam( nOut, dParSOut, dParEOut) -- creo composita corrispondente al pezzo local nCompo = EgtCurveCompo( nGrp, {vCrvsIn[i]}, false) EgtAddCurveCompoLine( nCompo, ptSOut) EgtAddCurveCompoCurve( nCompo, nOut, false) EgtCloseCurveCompo( nCompo) -- calcolo il frame per il tronchetto local ptM = EgtMP( vCrvsIn[i]) local vtRad = ptM - ptC local frRef = Frame3d( ptM, vtRad ^ Z_AX(), vtRad, Z_AX()) -- calcolo il box locale al frame local b3Ref = EgtGetBBoxRef( nCompo, GDB_BB.STANDARD, frRef) local ptMin = b3Ref:getMin() local ptMax = b3Ref:getMax() -- verifico se necessario sovramateriale extra per raggiungere la sezione desiderata local dExtraSection = max( 0, dRefSection - b3Ref:getDimY() - dOverMatIn - dOverMatOut) -- lato bottom local nLineBottom = EgtLinePVL( nGrp, ptMin - ( dOverMatIn + 0.5 * dExtraSection) * Y_AX(), X_AX(), 10000) EgtExtendCurveStartByLen( nLineBottom, 10000) EgtTransform( nLineBottom, frRef) -- lato top local nLineTop = EgtLinePVL( nGrp, ptMax + ( dOverMatOut + 0.5 * dExtraSection) * Y_AX(), - X_AX(), 10000) EgtExtendCurveStartByLen( nLineTop, 10000) EgtTransform( nLineTop, frRef) -- lato right local nLineRight if i == 1 and not bCutExtremities then nLineRight = EgtLinePVL( nGrp, ptMin, - Y_AX(), 10000) EgtTransform( nLineRight, frRef) else nLineRight = EgtLine( nGrp, ptEOut, ptSIn) EgtExtendCurveEndByLen( nLineRight, 10000) end EgtOffsetCurve( nLineRight, EgtIf( i == 1, dOverMatExt, dOverMatInt)) EgtExtendCurveStartByLen( nLineRight, 10000) -- lato left local nLineLeft if i == #vCrvsIn and not bCutExtremities then nLineLeft = EgtLinePVL( nGrp, ptMax, Y_AX(), 10000) EgtTransform( nLineLeft, frRef) else nLineLeft = EgtLine( nGrp, ptEIn, ptSOut) EgtExtendCurveEndByLen( nLineLeft, 10000) end EgtOffsetCurve( nLineLeft, EgtIf( i == #vCrvsIn, dOverMatExt, dOverMatInt)) EgtExtendCurveStartByLen( nLineLeft, 10000) -- taglio le curve nei loro punti di intersezione local vCrvs = { nLineTop, nLineRight, nLineBottom, nLineLeft} TrimAndOrientOrderedCurves( vCrvs, false) -- TO DO : controllo lunghezza minima -- local dLenTop = EgtCurveLength( nLineTop) -- creo il tronchetto local nLogCrv = EgtCurveCompo( nGrp, vCrvs) EgtSetName( nLogCrv, WIN_LOGS) EgtSetColor( nLogCrv, EgtStdColor( 'BLUE')) -- salvo i sovramateriali utilizzati nella curva EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_IN, dOverMatIn) EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_OUT, dOverMatOut) EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_LEFT, EgtIf( i == #vCrvsIn, dOverMatExt, dOverMatInt)) EgtSetInfo( nLogCrv, WIN_PRC_OVERMAT_RIGHT, EgtIf( i == 1, dOverMatExt, dOverMatInt)) EgtSetStatus( vCrvsIn[i], GDB_ST.OFF) EgtSetStatus( nOut, GDB_ST.OFF) EgtErase( nCompo) end end --------------------------------------------------------------------- -- funzione che calcola i tronchetti di un pezzo ad arco function WinCalculate.CreateArcLogs( nPartId, nLogsNbr, vSections, bAlign, dOverMatOut, dOverMatIn, dOverMatExt, dOverMatInt, bCutExtremities) -- verifico dati in ingresso if bAlign then nLogsNbr = 0 end if not bAlign and nLogsNbr == 0 and ( #vSections == 0 or #vSections > 1) then return end -- recupero o creo il gruppo per i tronchetti local nGrp = EgtGetFirstNameInGroup( nPartId, WIN_LOGS) if not nGrp then nGrp = EgtGroup( nPartId) EgtSetName( nGrp, WIN_LOGS) else EgtEmptyGroup( nGrp) end -- recupero il geo del pezzo local nGeoLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local nGeoIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) local nGeoOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) -- spezzo l'arco interno SplitArc( nLogsNbr, vSections, bAlign, dOverMatOut + dOverMatIn, nGeoIn, nGeoOut, nGrp) -- calcolo la sezione di riferimento per i tronchetti local dSection = CalcLogsSection( nLogsNbr, vSections, bAlign, dOverMatOut + dOverMatIn, nGeoIn, nGeoOut, nGrp) if not dSection then return end -- creo i tronchetti CalcLogs( nGrp, nGeoOut, dOverMatIn, dOverMatOut, dOverMatExt, dOverMatInt, dSection, bCutExtremities) end ---------------------------------------------------------------------------------- ------------------------------ FUNZIONI ---------------------------------------- ---------------------------------------------------------------------------------- -- funzione che crea tutti i pezzi della finestra partendo dal telaio function WinCalculate.CreatePartFromArea( nFrameId) -- assegno il tipo di profilo alle curve del base outline CalculateAreaProfileType( nFrameId) -- calcolo outline a partire dal base outline CalculateAreaOutline( nFrameId) -- creo pezzi CalculateAreaParts( nFrameId) -- calcolo le spine CalculateAreaDowels( nFrameId) end --------------------------------------------------------------------- -- funzione che posiziona un pezzo function WinCalculate.PositionPart(nPartId) -- ricavo tipo dal nome local sName = EgtGetName( nPartId) local sDelta = '' if sName == WIN_BOTTOM then sDelta = WIN_STARTCPDELTA elseif sName == WIN_RIGHT then sDelta = WIN_STARTCPDELTA elseif sName == WIN_TOP then sDelta = WIN_STARTCPDELTA elseif sName == WIN_LEFT then sDelta = WIN_STARTCPDELTA end -- calcolo nuovo riferimento local nGeoPartLayerId = EgtGetFirstNameInGroup( nPartId, WIN_GEO) local nGeoPartId = EgtGetFirstNameInGroup( nGeoPartLayerId, sName) local dDelta = EgtGetInfo( nGeoPartId, sDelta, 'd') or 0 local nFrameLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_FRAME) local nOutlineLayerId = EgtGetFirstNameInGroup( nFrameLayerId, WIN_OUTLINE) local nFramePartId = EgtGetFirstNameInGroup( nOutlineLayerId, sName) local vtStart = EgtSV( nFramePartId) local ptStart = EgtSP( nFramePartId) + vtStart * dDelta local _, _, dAngRight = SphericalFromVector(vtStart) local frStart = Frame3d( ptStart) frStart:rotate( frStart:getOrigin(), Z_AX(), dAngRight) EgtChangeGroupFrame( nPartId, frStart) end --------------------------------------------------------------------- -- funzione che assembla i pezzi function WinCalculate.AssembleFrame() local nBottomPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_BOTTOM) WinCalculate.PositionPart(nBottomPartId) local nRightPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_RIGHT) WinCalculate.PositionPart(nRightPartId) local nTopPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_TOP) WinCalculate.PositionPart(nTopPartId) local nLeftPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_LEFT) WinCalculate.PositionPart(nLeftPartId) -- assemblo i pezzi --local nRightPartId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_RIGHT) --local nGeoRightLayerId = EgtGetFirstNameInGroup( nRightPartId, WIN_GEO) --local nGeoRightId = EgtGetFirstNameInGroup( nGeoRightLayerId, WIN_RIGHT) --local dDelta = EgtGetInfo( nGeoRightId, WIN_BOTTOMCPDELTA, 'd') --local nFrameLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_FRAME) --local nOutlineLayerId = EgtGetFirstNameInGroup( nFrameLayerId, WIN_OUTLINE) --local nFrameRightId = EgtGetFirstNameInGroup( nOutlineLayerId, WIN_RIGHT) --local vtRight = EgtSV( nFrameRightId) --local ptRight = EgtSP( nFrameRightId) + vtRight * dDelta --local _, _, dAngRight = SphericalFromVector(vtRight) --local frRight = Frame3d( ptRight) --frRight:rotate( frRight:getOrigin(), Z_AX(), dAngRight) --EgtChangeGroupFrame( nRightPartId, frRight) end ---------------------------------------------------------------------------------- ------------------- POST PROCESSING PER AUTOMATISMO LAVORAZIONI ------------------ ---------------------------------------------------------------------------------- -- funzione che crea la spina per tronchetti local function CalcLogDowel( nOrigPartId, nCrvOut, bLeftOrRight, nProcLayerId, nProfileId, nInfoGrp, nSolidId) -- creo il frame per il posizionamento del dowel local nOutlineRef = EgtGetInfo( nOrigPartId, WIN_REF_OUTLINE, 'i') local ptRef = EgtIf( bLeftOrRight, EgtSP( nCrvOut), EgtEP( nCrvOut)) local _, ptOrig, dParOrig = EgtPointCurveDist( ptRef, nOutlineRef) local vtFrame = EgtUV( nOutlineRef, dParOrig, -1) local frDest = Frame3d( ptOrig, - vtFrame) -- calcolo direzione verso interno del pezzo local vtDir = frDest:getVersZ() if bLeftOrRight then vtDir = - vtDir end -- recupero i dati del dowel local dDowelDiam = EgtGetInfo( nInfoGrp, WIN_DWL_DIAM, 'd') local dDowelLen = EgtGetInfo( nInfoGrp, WIN_DWL_LOG_LEN, 'd') -- creo il dowel nel riferimento della sezione -- TO DO : recupero della sezione corretta nel caso di cambio profilo local nSectionId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTION) or EgtGetFirstNameInGroup( nProfileId, WIN_SASH .. WIN_SECTION) local nDowelId = EgtCircle( nProcLayerId, EgtGP( nSectionId), 0.5 * dDowelDiam) -- posiziono il dowel usando i riferimenti local nFrameId = EgtGetFirstNameInGroup( nProfileId, WIN_SECTIONFRAME) local frOrig = EgtFR( nFrameId) frOrig:invert() EgtTransform( nDowelId, frOrig) EgtTransform( nDowelId, frDest) local nPartId = EgtGetParent( nProcLayerId) local dOverMat = EgtGetInfo( nPartId, EgtIf( bLeftOrRight, WIN_PRC_OVERMAT_LEFT, WIN_PRC_OVERMAT_RIGHT)) EgtMove( nDowelId, - vtDir * ( s_dDowelTol + dOverMat)) EgtModifyCurveExtrusion( nDowelId, - vtDir) local dLen = dDowelLen + dOverMat + s_dDowelTol EgtModifyCurveThickness( nDowelId, - dLen) -- setto info di lavorazione EgtSetInfo( nDowelId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE) EgtSetInfo( nDowelId, WIN_PRC_SIDE, EgtIf( bLeftOrRight, WIN_PRC_SIDETYPE.LEFT, WIN_PRC_SIDETYPE.RIGHT)) -- eventuale aggiornamento del solido if nSolidId then UpdateSolidWithDowel( nDowelId, nSolidId, vtDir, dLen, nProcLayerId) end end --------------------------------------------------------------------- -- funzione che crea il pezzo del tronchetto local function PrepareLogPart( nOrigPartId, nCrvIn, nCrvOut, bFirst, bLast, bFinishedLog, nInfoGrp) local nPartId = EgtGroup( GDB_ID.ROOT) EgtSetName( nPartId, WIN_LOGS) EgtSetColor( nPartId, Color3d( 204, 102, 0)) local nLogCrv = EgtGetNext( nCrvOut) -- setto le info con i sovramateriali corrispondenti CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_IN, 0) CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_OUT, 0) CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_LEFT, 0) CopyInfo( nPartId, nLogCrv, WIN_PRC_OVERMAT_RIGHT, 0) -- recupero il profilo local nProfileLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_PROFILE) local nProfileId = EgtGetFirstNameInGroup( nProfileLayerId, WIN_PRF_MAIN) -- a) GEORAW local nGeoRawLayerId = EgtGroup( nPartId) EgtSetName( nGeoRawLayerId, WIN_GEO_RAW) EgtCopyGlob( nLogCrv, nGeoRawLayerId) -- creo il frame ausiliario local vtX = EgtSV( nLogCrv) local frGeo = Frame3d( EgtSP( nLogCrv), vtX, Z_AX() ^ vtX, Z_AX()) local nFrameId = EgtFrame( nGeoRawLayerId, frGeo) EgtSetName( nFrameId, WIN_PRC_FRAME) -- b) SOLIDO local nSolidId if s_bCalcSolid then local nSolidLayerId = EgtGroup( nPartId) EgtSetName( nSolidLayerId, WIN_SOLID) if bFirst and bLast then -- essendo singolo pezzo il solido è quello originale local nOrigSolidLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_SOLID) local nOrigSolidId = EgtGetFirstNameInGroup( nOrigSolidLayerId, WIN_SRF_MAIN) EgtRelocateGlob( nOrigSolidId, nSolidLayerId) elseif bFinishedLog then -- recupero il solido originale e lo taglio opportunamente agli estremi local nOrigSolidLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_SOLID) local nOrigSolidId = EgtGetFirstNameInGroup( nOrigSolidLayerId, WIN_SRF_MAIN) nSolidId = EgtCopyGlob( nOrigSolidId, nSolidLayerId) local bBox = GetProfileLocalBox( nProfileId) local dDimY = bBox:getDimY() if not bFirst then local nTrimCrv = EgtLine( nSolidLayerId, EgtUP( nLogCrv, 2), EgtUP( nLogCrv, 1)) EgtMove( nTrimCrv, Z_AX()) local nTrimSrf = EgtSurfTmByExtrusion( nSolidLayerId, nTrimCrv, - Z_AX() * ( dDimY + 2), WIN_SURF_APPROX) EgtSurfTmIntersect( nSolidId, nTrimSrf) EgtErase( { nTrimCrv, nTrimSrf}) end if not bLast then local nTrimCrv = EgtLine( nSolidLayerId, EgtSP( nLogCrv), EgtUP( nLogCrv, 3)) EgtMove( nTrimCrv, Z_AX()) local nTrimSrf = EgtSurfTmByExtrusion( nSolidLayerId, nTrimCrv, - Z_AX() * ( dDimY + 2), WIN_SURF_APPROX) EgtSurfTmIntersect( nSolidId, nTrimSrf) EgtErase( { nTrimCrv, nTrimSrf}) end else -- il solido è esattamente il tronchetto local bBox = GetProfileLocalBox( nProfileId) nSolidId = EgtSurfTmByRegionExtrusion( nSolidLayerId, nLogCrv, - bBox:getDimY() * Z_AX()) EgtSetName( nSolidId, WIN_SOLID) end end -- c) LAVORAZIONI local nOrigProcLayerId = EgtGetFirstNameInGroup( nOrigPartId, WIN_PRC) -- se unico tronchetto le lavorazioni sono quelle del pezzo originale if bFirst and bLast then EgtRelocateGlob( nOrigProcLayerId, nPartId) EgtSetStatus( nOrigProcLayerId, GDB_ST.ON) return end local nProcLayerId = EgtGroup( nPartId) EgtSetName( nProcLayerId, WIN_PRC) -- profili in e out if bFinishedLog then EgtRelocateGlob( nCrvIn, nProcLayerId) local nSemiProfileInId = EgtGetInfo( nCrvIn, WIN_SEMI_PROFILE, 'i') GetProcessingInfoFromSemiProfile( nCrvIn, nSemiProfileInId) EgtSetStatus( nCrvIn, GDB_ST.ON) EgtRelocateGlob( nCrvOut, nProcLayerId) local nSemiProfileOutId = EgtGetInfo( nCrvOut, WIN_SEMI_PROFILE, 'i') GetProcessingInfoFromSemiProfile( nCrvOut, nSemiProfileOutId) EgtSetStatus( nCrvOut, GDB_ST.ON) end -- profilo left if bLast and bFinishedLog then -- recupero la curva di lavorazione dal pezzo originale local nLeftPrc = EgtGetFirstNameInGroup( nOrigProcLayerId, WIN_GEO_LEFT) EgtRelocateGlob( nLeftPrc, nProcLayerId) elseif not bLast then -- minizinken local nLeftId = EgtLine( nProcLayerId, EgtUP( nLogCrv, 3), EgtSP( nLogCrv)) EgtSetName( nLeftId, WIN_LEFT) -- assegno le info di lavorazione EgtSetInfo( nLeftId, WIN_PRC_NTOOLS, 1) local sToolName = EgtGetInfo( nInfoGrp, WIN_PRC_TOOL_NAME) EgtSetInfo( nLeftId, WIN_PRC_TOOL_NAME .. '_1', sToolName) local dOffR = EgtGetInfo( nInfoGrp, WIN_PRC_OFFR, 'd') -- TO DO : verificare valore OffsR EgtSetInfo( nLeftId, WIN_PRC_OFFR .. '_1', dOffR) local dOffL = EgtGetInfo( nInfoGrp, WIN_PRC_OFFL .. '_1', 'd') EgtSetInfo( nLeftId, WIN_PRC_OFFL .. '_1', dOffL) end -- profilo right if bFirst and bFinishedLog then -- recupero la curva di lavorazione dal pezzo originale local nRightPrc = EgtGetFirstNameInGroup( nOrigProcLayerId, WIN_GEO_RIGHT) EgtRelocateGlob( nRightPrc, nProcLayerId) elseif not bFirst then -- minizinken local nRightId = EgtLine( nProcLayerId, EgtUP( nLogCrv, 1), EgtUP( nLogCrv, 2)) EgtSetName( nRightId, WIN_RIGHT) -- assegno info di lavorazione EgtSetInfo( nRightId, WIN_PRC_NTOOLS, 1) local sToolName = EgtGetInfo( nInfoGrp, WIN_PRC_TOOL_NAME) EgtSetInfo( nRightId, WIN_PRC_TOOL_NAME .. '_1', sToolName) local dOffR = EgtGetInfo( nInfoGrp, WIN_PRC_OFFR, 'd') -- TO DO : verificare valore OffsR EgtSetInfo( nRightId, WIN_PRC_OFFR .. '_1', dOffR) local dOffL = EgtGetInfo( nInfoGrp, WIN_PRC_OFFL .. '_2', 'd') EgtSetInfo( nRightId, WIN_PRC_OFFL .. '_1', dOffL) end -- dowels per incastro dei tronchetti if not bFirst then CalcLogDowel( nOrigPartId, nCrvOut, false, nProcLayerId, nProfileId, nInfoGrp, nSolidId) end if not bLast then CalcLogDowel( nOrigPartId, nCrvOut, true, nProcLayerId, nProfileId, nInfoGrp, nSolidId) end -- se i tronchetti sono gestiti come pezzi finiti cerco le lavorazioni del pezzo orginale che appartengono al tronchetto if bFinishedLog then local vProcessings = EgtGetAllInGroup( nOrigProcLayerId) local nSurfTest = EgtSurfFlatRegion( nProcLayerId, nLogCrv) for i = 1, #vProcessings do local sPrcType = EgtGetInfo( vProcessings[i], WIN_PRC_FEATURE_TYPE) -- forature if sPrcType == WIN_PRC_TYPE.HOLE then local sSide = EgtGetInfo( vProcessings[i], WIN_PRC_SIDE) -- se dowel sull'estremo lo assegno direttamente al tronchetto corrispondente if ( sSide == WIN_PRC_SIDETYPE.LEFT and bLast) or ( sSide == WIN_PRC_SIDETYPE.RIGHT and bFirst) then EgtRelocateGlob( vProcessings[i], nProcLayerId) end -- altrimenti verifico se interno al tronchetto corrente if sSide == WIN_PRC_SIDETYPE.IN then local _, _, nSide = EgtPointCurveDistSide( EgtCP( vProcessings[i]), nLogCrv, Z_AX()) if nSide == -1 then -- copio perchè la stessa lavorazione potrebbe coinvolgere più tronchetti EgtCopyGlob( vProcessings[i], nProcLayerId) else -- verifico anche la faccia di fondo local vtExtr = EgtCurveExtrusion( vProcessings[i]) local dThickness = EgtCurveThickness( vProcessings[i]) _, _, nSide = EgtPointCurveDistSide( EgtCP( vProcessings[i]) + dThickness * vtExtr, nLogCrv, Z_AX()) if nSide == -1 then EgtCopyGlob( vProcessings[i], nProcLayerId) end end end -- fermavetro elseif sPrcType == WIN_PRC_TYPE.STRIP_CUT then -- TO DO da sistemare local nStrip = EgtCopyGlob( vProcessings[i], nProcLayerId) EgtTrimCurveWithRegion( nStrip, nSurfTest, true, false) else -- TO DO lavorazioni legate alla ferramenta, cambio profilo end end EgtErase( nSurfTest) end end --------------------------------------------------------------------- -- funzione che crea gli elementi ausiliari per la creazione del grezzo nell'automatismo local function PrepareGeoRawCurve( nPartId, nGeoRawLayerId, nGeoLayerId) -- recupero le curve del geo local nOut = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_OUT) local nIn = EgtGetFirstNameInGroup( nGeoLayerId, WIN_GEO_IN) local vRight = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_RIGHT) local vLeft = EgtGetNameInGroup( nGeoLayerId, WIN_GEO_LEFT) -- verifico se le curve right e left hanno direzioni coerenti if #vRight == 2 and not AreSamePointApprox( EgtEP( vRight[1]), EgtSP( vRight[2])) then -- la seconda curva va ignorata EgtErase( vRight[2]) vRight = { vRight[1]} end if #vLeft == 2 and not AreSamePointApprox( EgtEP( vLeft[1]), EgtSP( vLeft[2])) then -- la prima curva va ignorata EgtErase( vLeft[1]) vLeft = { vLeft[2]} end -- recupero i sovramateriali da applicare alle curve local dOvermatOut = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_OUT, 'd') local dOvermatRight = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_RIGHT, 'd') local dOvermatIn = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_IN, 'd') local dOvermatLeft = EgtGetInfo( nPartId, WIN_PRC_OVERMAT_LEFT, 'd') -- applico i sovramateriali EgtOffsetCurve( nOut, dOvermatOut) for i = 1, #vRight do EgtOffsetCurve( vRight[i], dOvermatRight) end EgtOffsetCurve( nIn, dOvermatIn) for i = 1, #vLeft do EgtOffsetCurve( vLeft[i], dOvermatLeft) end -- creo la composita a partire dalle curve local vCrvs = EgtGetAllInGroup( nGeoLayerId) TrimAndOrientOrderedCurves( vCrvs, false) local nCompo = EgtCurveCompo( nGeoRawLayerId, vCrvs) return nCompo end --------------------------------------------------------------------- -- funzione che crea gli elementi ausiliari per la creazione del grezzo nell'automatismo nel caso di arco spezzato in tronchetti local function PrepareGeoRawCurveFromLogs( nPartId, nGeoRawLayerId, nLogsLayerId) -- recupero i vari tronchetti local vLogCrvs = EgtGetNameInGroup( nLogsLayerId, WIN_LOGS) -- salvo le info di sovramateriale nel pezzo CopyInfo( nPartId, vLogCrvs[1], WIN_PRC_OVERMAT_IN, 0) CopyInfo( nPartId, vLogCrvs[1], WIN_PRC_OVERMAT_OUT, 0) local nOvermatLateral = EgtGetInfo( vLogCrvs[1], WIN_PRC_OVERMAT_RIGHT, 'd') EgtSetInfo( nPartId, WIN_PRC_OVERMAT_RIGHT, nOvermatLateral) EgtSetInfo( nPartId, WIN_PRC_OVERMAT_LEFT, nOvermatLateral) -- costruisco il grezzo a partire dai tronchetti local vCrvs = {} local vIdIn = {} -- recupero le curve in e out dei tronchetti for i = #vLogCrvs, 1, -1 do local nLineOut = EgtLine( nGeoRawLayerId, EgtUP( vLogCrvs[i], 0), EgtUP( vLogCrvs[i], 1)) local nLineIn = EgtLine( nGeoRawLayerId, EgtUP( vLogCrvs[i], 2), EgtUP( vLogCrvs[i], 3)) table.insert( vCrvs, nLineOut) table.insert( vIdIn, nLineIn) end local nLineR = EgtLine( nGeoRawLayerId, EgtEP( vCrvs[#vCrvs]), EgtSP( vIdIn[#vIdIn])) table.insert( vCrvs, nLineR) for i = #vIdIn, 1, -1 do table.insert( vCrvs, vIdIn[i]) end local nLineL = EgtLine( nGeoRawLayerId, EgtEP( vIdIn[1]), EgtSP( vCrvs[1])) table.insert( vCrvs, nLineL) -- taglio le curve nelle intersezioni ( va eliminato il sovramateriale per minizinken) TrimAndOrientOrderedCurves( vCrvs, false) -- costruisco la compo del grezzo local nCompo = EgtCurveCompo( nGeoRawLayerId, vCrvs) return nCompo end --------------------------------------------------------------------- -- funzione che prepara il progetto per passarlo all'automatismo delle lavorazioni function WinCalculate.PrepareProject() -- recupero il gruppo dei profili local nProfileLay = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE) local nInfoGrp = EgtGetFirstNameInGroup( nProfileLay, WIN_INFO_GRP) -- elimino i pezzi di tipo fill local vFills = EgtGetNameInGroup( GDB_ID.ROOT, WIN_FILL) EgtErase( vFills) -- TO DO : recupero modalità di lavorazione dei tronchetti local bFinishedLogs = true -- preparo ogni pezzo per l'automatismo ( quindi salto i primi due che sono il gruppo dei profili e delle aree) local vParts = EgtGetAllInGroup( GDB_ID.ROOT) for i = 3, #vParts do local bDeletePart = false -- verifico se tronchetti local nLogsLayerId = EgtGetFirstNameInGroup( vParts[i], WIN_LOGS) if nLogsLayerId then -- calcolo i pezzi corrispondenti ai tronchetti local vCrvIn = EgtGetNameInGroup( nLogsLayerId, WIN_GEO_IN) local vCrvOut = EgtGetNameInGroup( nLogsLayerId, WIN_GEO_OUT) for j = 1, #vCrvIn do PrepareLogPart( vParts[i], vCrvIn[j], vCrvOut[j], j == 1, j == #vCrvIn, bFinishedLogs, nInfoGrp) end -- il pezzo originale va cancellato se i tronchetti sono lavorati come pezzi finiti oppure se c'è un solo tronchetto bDeletePart = bFinishedLogs or ( #vCrvIn == 1) end if bDeletePart then EgtErase( vParts[i]) else -- cancello il gruppo dei profili local nProfileGrp = EgtGetFirstNameInGroup( vParts[i], WIN_PROFILE) EgtErase( nProfileGrp or GDB_ID.NULL) -- cancello eventuali gruppi ausiliari per cambio profilo local nMixedOutlines = EgtGetFirstNameInGroup( vParts[i], WIN_MIXED_OUTLINES) EgtErase( nMixedOutlines or GDB_ID.NULL) local nMixedIntersections = EgtGetFirstNameInGroup( vParts[i], WIN_MIXED_INTERSECTIONS) EgtErase( nMixedIntersections or GDB_ID.NULL) -- accendo gruppo delle lavorazioni local nProcLay = EgtGetFirstNameInGroup( vParts[i], WIN_PRC) EgtSetStatus( nProcLay, GDB_ST.ON) -- nel gruppo dei solidi conservo solo quello principale local nSolidGrp = EgtGetFirstNameInGroup( vParts[i], WIN_SOLID) if nSolidGrp then local nMainSolid = EgtGetFirstNameInGroup( nSolidGrp, WIN_SRF_MAIN) local vIds = EgtGetAllInGroup( nSolidGrp) for i = 1, #vIds do if vIds[i] ~= nMainSolid then EgtErase( vIds[i]) end end end -- creo il GeoRaw per il calcolo del grezzo local nGeoRawLayerId = EgtGroup( vParts[i]) EgtSetName( nGeoRawLayerId, WIN_GEO_RAW) local nGeoLayerId = EgtGetFirstNameInGroup( vParts[i], WIN_GEO) local nCompo if nLogsLayerId then nCompo = PrepareGeoRawCurveFromLogs( vParts[i], nGeoRawLayerId, nLogsLayerId) EgtErase( nLogsLayerId) else nCompo = PrepareGeoRawCurve( vParts[i], nGeoRawLayerId, nGeoLayerId) end EgtErase( nGeoLayerId) -- creo frame ausiliario local vtX = EgtSV( nCompo) local frGeo = Frame3d( EgtSP( nCompo), vtX, Z_AX() ^ vtX, Z_AX()) local nFrameId = EgtFrame( nGeoRawLayerId, frGeo) EgtSetName( nFrameId, WIN_PRC_FRAME) end end -- elimino il gruppo delle aree local nAreaLay = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_AREA .. '*') EgtErase( nAreaLay) -- elimino il gruppo dei profili EgtErase( nProfileLay) end ---------------------------------------------------------------------------------- ---------------------------------- FERRAMENTA ---------------------------------- ---------------------------------------------------------------------------------- local function SearchSash( nAreaId, SashList) -- verifico il tipo local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') --if nAreaType == WIN_AREATYPES.FRAME then if nAreaType == WIN_AREATYPES.SASH then -- calcolo il Box local nOutlineLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_OUTLINE) local b3Outline = EgtGetBBox( nOutlineLayerId, GDB_BB.STANDARD) -- recupero punti di origine local nSashFrameLayerId = EgtGroup( nAreaId) EgtSetName( nSashFrameLayerId, WIN_HDW_FRAME) local vOutlineCopy = {} local nOutlineOffsetLayerId = EgtGroup( nAreaId) local nOutlineId = EgtGetFirstInGroup( nOutlineLayerId) while nOutlineId do local sProfileType = EgtGetInfo( nOutlineId, WIN_PROFILETYPE) local nProfileId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE, 'i') local nSashProfileId = EgtGetFirstNameInGroup( nProfileId, WIN_SASH, 'i') local nSashProfileTypeId = EgtGetFirstNameInGroup( nSashProfileId, sProfileType, 'i') local dGapDelta = EgtGetInfo( nSashProfileTypeId, WIN_GAPDELTA, 'd') local dGapDeltaZ = EgtGetInfo( nSashProfileTypeId, WIN_GAPDELTAZ, 'd') local nOutlineCopyId = EgtCopy( nOutlineId, nOutlineOffsetLayerId) EgtSetInfo( nOutlineCopyId, 'ORIG', nOutlineId) EgtSetInfo( nOutlineCopyId, WIN_GAPDELTAZ, dGapDeltaZ) local nSectionFrameId = EgtGetFirstNameInGroup( nSashProfileTypeId, WIN_SECTIONFRAME) local frSectionFrame = EgtFR( nSectionFrameId) local nSashProfileRefId = EgtGetFirstNameInGroup( nSashProfileTypeId, WIN_REF) local b3SashProfileType = EgtGetBBoxRef( nSashProfileRefId, GDB_BB.STANDARD, frSectionFrame) EgtSetInfo( nOutlineCopyId, WIN_GAPDELTAZ .. 2, b3SashProfileType:getDimY()) EgtOffsetCurve( nOutlineCopyId, - dGapDelta) table.insert( vOutlineCopy, nOutlineCopyId) nOutlineId = EgtGetNext( nOutlineId) end local tSash = { nAreaId = nAreaId, ptCenter = b3Outline:getCenter()} local tFrame = {} local nA_FA1Id = GDB_ID.NULL local nB_FA1Id = GDB_ID.NULL local nC_FA1Id = GDB_ID.NULL local nD_FA1Id = GDB_ID.NULL for nIndex = 1, #vOutlineCopy do local nNext = EgtIf( nIndex < #vOutlineCopy, nIndex + 1, 1) local ptOrig = EgtIP( vOutlineCopy[nIndex], vOutlineCopy[nNext], ORIG()) local dParam = EgtCurveParamAtPoint( vOutlineCopy[nIndex], ptOrig) EgtTrimCurveEndAtParam( vOutlineCopy[nIndex], dParam) dParam = EgtCurveParamAtPoint( vOutlineCopy[nNext], ptOrig) EgtTrimCurveStartAtParam( vOutlineCopy[nNext], dParam) local sOrigName = string.char(string.byte('A') + #vOutlineCopy - nIndex) tSash[sOrigName] = ptOrig local vtDir = EgtEV( vOutlineCopy[nIndex]) local nFA1Id = EgtFrame( nSashFrameLayerId, Frame3d( ptOrig, - vtDir, vtDir ^ Z_AX() , Z_AX())) EgtSetName( nFA1Id, sOrigName .. '.FA1') local vtIn = Vector3d( vtDir) vtIn:rotate( Z_AX(), -90) local dGapDeltaZ = EgtGetInfo( vOutlineCopy[nIndex], WIN_GAPDELTAZ, 'd') local nFA2Id = EgtFrame( nSashFrameLayerId, Frame3d( ptOrig - dGapDeltaZ * Z_AX(), - vtDir, vtDir ^ vtIn , vtIn)) EgtSetName( nFA2Id, sOrigName .. '.FA2') local dGapDeltaZ2 = EgtGetInfo( vOutlineCopy[nIndex], WIN_GAPDELTAZ .. 2, 'd') local nFA3Id = EgtFrame( nSashFrameLayerId, Frame3d( ptOrig - dGapDeltaZ2 * Z_AX(), - vtDir, vtDir ^ -Z_AX() , -Z_AX())) EgtSetName( nFA3Id, sOrigName .. '.FA3') if sOrigName == 'A' then nA_FA1Id = nFA1Id elseif sOrigName == 'B' then nB_FA1Id = nFA1Id elseif sOrigName == 'C' then nC_FA1Id = nFA1Id elseif sOrigName == 'D' then nD_FA1Id = nFA1Id end -- ricavo posizione sul telaio local nOrigOutlineId = EgtGetInfo( vOutlineCopy[nIndex], 'ORIG', 'i') local nBaseOutlineId = EgtGetInfo( nOrigOutlineId, WIN_COPY, 'i') local nSouId = EgtGetInfo( nBaseOutlineId, WIN_SOU, 'i') local nSouAreaId = EgtGetParent( EgtGetParent( nSouId)) local nSouAreaType = EgtGetInfo( nSouAreaId, WIN_AREATYPE, 'i') while nSouId and nSouAreaType ~= WIN_AREATYPES.FRAME do nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i') nSouAreaId = EgtGetParent( EgtGetParent( nSouId or GDB_ID.NULL)) nSouAreaType = EgtGetInfo( nSouAreaId or GDB_ID.NULL, WIN_AREATYPE, 'i') end if nSouId and EgtGetName( nSouId) ~= WIN_SPLIT then local nFrameFrameLayerId = EgtGetFirstNameInGroup( nSouAreaId, WIN_HDW_FRAME) if not nFrameFrameLayerId then nFrameFrameLayerId = EgtGroup( nSouAreaId) EgtSetName( nFrameFrameLayerId, WIN_HDW_FRAME) end -- ricavo aria lato telaio local sProfileType = EgtGetInfo( nSouId, WIN_PROFILETYPE) local nProfileId = EgtGetFirstNameInGroup( GDB_ID.ROOT, WIN_PROFILE, 'i') local nFrameProfileId = EgtGetFirstNameInGroup( nProfileId, WIN_FRAME, 'i') local nFrameProfileTypeId = EgtGetFirstNameInGroup( nFrameProfileId, sProfileType, 'i') local dGapDeltaOut = EgtGetInfo( nFrameProfileTypeId, WIN_GAPDELTAOUT, 'd') local dFrameGapDeltaZ = EgtGetInfo( nFrameProfileTypeId, WIN_GAPDELTAZ, 'd') local nOutlineOutId = EgtCopy( nSouId, nOutlineOffsetLayerId) EgtSetName( nOutlineOutId, 'Frame') EgtOffsetCurve( nOutlineOutId, - dGapDeltaOut) -- prendo la proiezione _, ptOrig = EgtPointCurveDist( ptOrig, nOutlineOutId) -- recupero DeltaZ2 local nSectionFrameId = EgtGetFirstNameInGroup( nFrameProfileTypeId, WIN_SECTIONFRAME) local frSectionFrame = EgtFR( nSectionFrameId) local nFrameProfileRefId = EgtGetFirstNameInGroup( nFrameProfileTypeId, WIN_REF) local b3SashProfileType = EgtGetBBoxRef( nFrameProfileRefId, GDB_BB.STANDARD, frSectionFrame) local nFT1Id = EgtFrame( nFrameFrameLayerId, Frame3d( ptOrig - dFrameGapDeltaZ * Z_AX(), - vtDir, vtDir ^ Z_AX() , Z_AX())) EgtSetName( nFT1Id, sOrigName .. '.FT1') table.insert( tFrame, nFT1Id) local vtFrameIn = Vector3d( vtDir) vtFrameIn:rotate( Z_AX(), 90) local nFT2Id = EgtFrame( nFrameFrameLayerId, Frame3d( ptOrig - dFrameGapDeltaZ * Z_AX(), - vtDir, vtDir ^ vtFrameIn , vtFrameIn)) EgtSetName( nFT2Id, sOrigName .. '.FT2') table.insert( tFrame, nFT2Id) local dGapDeltaZ2 = b3SashProfileType:getDimY() local nFT3Id = EgtFrame( nFrameFrameLayerId, Frame3d( ptOrig - dGapDeltaZ2 * Z_AX(), - vtDir, vtDir ^ -Z_AX() , -Z_AX())) EgtSetName( nFT3Id, sOrigName .. '.FT3') table.insert( tFrame, nFT3Id) end end tSash.Frame = tFrame tSash.LHeight = ( EgtSP( nB_FA1Id) - EgtSP( nA_FA1Id)):getY() tSash.RHeight = ( EgtSP( nC_FA1Id) - EgtSP( nD_FA1Id)):getY() tSash.TWidth = ( EgtSP( nC_FA1Id) - EgtSP( nB_FA1Id)):getX() tSash.BWidth = ( EgtSP( nD_FA1Id) - EgtSP( nA_FA1Id)):getX() if EgtGetType( vOutlineCopy[3]) == GDB_TY.CRV_ARC then tSash.BCLength = EgtCurveLength( vOutlineCopy[3]) tSash.BCArrow = EgtMP( vOutlineCopy[3]) - (( EgtEP( vOutlineCopy[3]) - EgtSP( vOutlineCopy[3])) / 2) end EgtErase( nOutlineOffsetLayerId) table.insert( SashList, tSash) end -- verifico se ci sono sotto-aree local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') while nChildAreaId do -- lancio costruzione pezzi di quell'area SearchSash( nChildAreaId, SashList) nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') end end -- funzione che aggiunge l'hardware function WinCalculate.AddHardwareForSash( nFrameId, bOnlyRequest) -- cerco ed indicizzo ante del serramento local SashList = {} SearchSash( nFrameId, SashList) -- ordino per X e Y local function compareXY(a,b) if abs( a.ptCenter:getX() - b.ptCenter:getX()) < GEO.EPS_SMALL then return a.ptCenter:getY() < b.ptCenter:getY() else return a.ptCenter:getX() < b.ptCenter:getX() end end table.sort(SashList, compareXY) -- correggo nomi Frame del telaio for nIndex = 1, #SashList do for nFrameIndex = 1, #SashList[nIndex].Frame do local nFrameId = SashList[nIndex].Frame[nFrameIndex] local sName = EgtGetName( nFrameId) EgtSetName( nFrameId, nIndex .. '.' .. sName) end end -- recupero preferito della ferramenta local nFavourite = EgtGetInfo( nFrameId, WIN_HDW_FAVOURITE) if not nFavourite or nFavourite == '000000' then EgtOutLog('Warning! No hardware favourite set!') return end local sHandle = EgtGetInfo( nFrameId, WIN_HDW_HANDLE) if not sHandle then EgtOutLog('Warning! No hardware handle set!') return end -- creo file di richiesta ferramenta local sNow = os.date( '_%Y_%m_%d_%H_%M_%S', os.time()) local sInputFile = 'a:\\InputBatch\\Input' .. sNow .. '.txt' local sAGBOutputFile = 'C:\\AGB3000NG\\OutputBatch\\Output' .. sNow .. '.txt' local sAGBOutputLavFile = 'C:\\AGB3000NG\\OutputBatch\\OutputLav' .. sNow .. '.txt' local sOutputFile = 'a:\\OutputBatch\\Output' .. sNow .. '.txt' local sOutputLavFile = 'a:\\OutputBatch\\OutputLav' .. sNow .. '.txt' -- Apro file Input in scrittura local fhInput = io.open( sInputFile, 'w') if not fhInput then EgtOutLog( 'Error opening file ' .. sInputFile) return false end local sText = 'OUTPUTKIT=' .. sAGBOutputFile .. '\n' .. 'S_NAME=' .. nFavourite .. '\n' .. 'RECORDID=15A' .. '\n' if #SashList >= 1 and SashList[1].LHeight == SashList[1].RHeight then sText = sText .. 'HBB=' .. tostring( SashList[1].LHeight) .. '\n' else for nSashIndex = 1, #SashList do if nSashIndex == 1 then sText = sText .. 'HBB_sx=' .. tostring( SashList[nSashIndex].LHeight) .. '\n' else sText = sText .. 'HBB_' .. tostring(nSashIndex - 1) .. 'B=' .. tostring( SashList[nSashIndex].LHeight) .. '\n' end if nSashIndex == #SashList then sText = sText .. 'HBB_dx=' .. tostring( SashList[nSashIndex].RHeight) .. '\n' else sText = sText .. 'HBB_' .. tostring(nSashIndex) .. '=' .. tostring( SashList[nSashIndex].RHeight) .. '\n' end end end if #SashList == 1 then sText = sText .. 'LBB=' .. tostring( SashList[1].BWidth) .. '\n' else for nSashIndex = 1, #SashList do sText = sText .. 'LBB' .. nSashIndex .. '=' .. tostring( SashList[nSashIndex].BWidth) .. '\n' if SashList[nSashIndex].BCLength then sText = sText .. 'LBBA' .. nSashIndex .. '=' .. tostring( SashList[nSashIndex].BCLength) .. '\n' end if SashList[nSashIndex].BCArrow then sText = sText .. 'FRECCIA_' .. nSashIndex .. '=' .. tostring( SashList[nSashIndex].BCArrow) .. '\n' end end end sText = sText .. 'FINESTRAPORTAFINESTRA=Finestra' .. '\n' .. 'Q=1' .. '\n' .. 'MANOSERRAMENTO=' .. sHandle .. '\n' .. 'CNCOUTPUT=' .. sAGBOutputLavFile .. '\n' .. 'RUN' -- Scrittura nuova linea fhInput:write( sText .. '\n') -- Chiudo file fhInput:close() if bOnlyRequest then return sInputFile end -- attendo scrittura output local nWait = 0 while not EgtExistsFile( sOutputFile) and nWait < 20 do nWait = nWait + 1 EgtPause( 500) end EgtPause( 500) -- Apro file Output in lettura local fhOutput = io.open( sOutputLavFile, 'r') if not fhOutput then EgtOutLog( 'Error opening file ' .. sOutputLavFile) return false end local sOutputLine = fhOutput:lines('l') for sMach in fhOutput:lines('l') do local MachParams = EgtSplitString( sMach, ';') local sPart = MachParams[3] local nSashIndex = tonumber( MachParams[4]) local sSashPart = MachParams[5] local dPosX = tonumber( MachParams[6]) local dPosY = tonumber( MachParams[7]) local dPosZ = tonumber( MachParams[8]) local sMacro = MachParams[9] local sSide = MachParams[21] -- FT1, FT2, FT3, FA1, FA2, FA3 local sOrigin = MachParams[24] -- AB, BC, CD, DA local nSashId = SashList[nSashIndex].nAreaId local nOutlineLayerId = EgtGetFirstNameInGroup( nSashId, WIN_OUTLINE) local vOutlineIds = EgtGetAllInGroup( nOutlineLayerId) local nA = string.byte('A') local nSashPart = string.byte(sSashPart) local nOutlineIndex = #vOutlineIds - (nSashPart - nA) local nOutlineId = vOutlineIds[nOutlineIndex] local nPartId = GDB_ID.NULL local frHdwFrame if sPart == 'TELAIO' then local nSashBaseOutlineId = EgtGetInfo( nOutlineId, WIN_COPY, 'i') local nSouId = EgtGetInfo( nSashBaseOutlineId, WIN_SOU, 'i') local nSouAreaId = EgtGetParent( EgtGetParent( nSouId)) local nSouAreaType = EgtGetInfo( nSouAreaId, WIN_AREATYPE, 'i') while nSouAreaType ~= WIN_AREATYPES.FRAME do nSouId = EgtGetInfo( nSouId, WIN_SOU, 'i') nSouAreaId = EgtGetParent( EgtGetParent( nSouId)) nSouAreaType = EgtGetInfo( nSouAreaId, WIN_AREATYPE, 'i') end local nFrameOutlineId = EgtGetInfo( nSouId, WIN_COPY, 'i') nPartId = EgtGetInfo( nFrameOutlineId, WIN_REF_PART, 'i') local nHdwFrameLayerId = EgtGetFirstNameInGroup( nSouAreaId, WIN_HDW_FRAME) local nHdwFrameId = EgtGetFirstNameInGroup( nHdwFrameLayerId, nSashIndex .. '.' .. sSashPart .. '.' .. sSide) frHdwFrame = EgtFR( nHdwFrameId) elseif sPart == 'ANTA' then nPartId = EgtGetInfo( nOutlineId, WIN_REF_PART, 'i') local nHdwFrameLayerId = EgtGetFirstNameInGroup( nSashId, WIN_HDW_FRAME) local nHdwFrameId = EgtGetFirstNameInGroup( nHdwFrameLayerId, sSashPart .. '.' .. sSide) frHdwFrame = EgtFR( nHdwFrameId) end local vMacro = EgtSplitString( sMacro, '_') local nProcLayerId = EgtGetFirstNameInGroup( nPartId, WIN_PRC) -- recupero solido ( se non calcolato non vengono utilizzate) local nSolidLayerId = EgtGetFirstNameInGroup( nPartId, WIN_SOLID) or GDB_ID.NULL local nMainExtrusionId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_MAIN) local nOrigMainId = EgtGetFirstNameInGroup( nSolidLayerId, WIN_SRF_ORIGMAIN) if vMacro[1] == 'FRESATA' then elseif vMacro[1] == 'ASOLA' then local ptCenter = Point3d( dPosX, dPosY, dPosZ) local dLength = tonumber( vMacro[2]) local dWidth = tonumber( vMacro[3]) local dHeight = tonumber( vMacro[4]) local ptP1 = ptCenter + ( dLength / 2 - dWidth) * X_AX() + dWidth * Y_AX() local ptP2 = ptCenter - ( dLength / 2 - dWidth) * X_AX() + dWidth * Y_AX() local nPocketOutlineId = EgtCurveCompoFromPoints( nProcLayerId, { ptP1, ptP2}) EgtAddCurveCompoArcTg( nPocketOutlineId, ptCenter - dLength / 2 * X_AX()) EgtAddCurveCompoArcTg( nPocketOutlineId, ptCenter + dLength / 2 * X_AX(), false) EgtSetColor( nPocketOutlineId, EgtStdColor( 'GRAY')) -- setto info di lavorazione EgtSetInfo( nPocketOutlineId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.PROFILING) EgtSetInfo( nPocketOutlineId, WIN_PRC_PROFILE_INFO, WIN_PRC_PROFILE_TYPE.GENERIC) EgtSetInfo( nPocketOutlineId, WIN_PRC_SIDE, WIN_PRC_SIDETYPE.IN) EgtModifyCurveExtrusion( nPocketOutlineId, Z_AX()) EgtModifyCurveThickness( nPocketOutlineId, - dHeight) -- aggiornamento del solido if s_bCalcSolid then -- costruisco asola come volume chiuso per eseguire operazioni booleane con il solido e la creo più grande per non avere geometrie a filo local dExtra = 1 local nOutlineId = EgtCopyGlob( nPocketOutlineId, nSolidLayerId) EgtAddCurveCompoLineTg( nOutlineId, dExtra) EgtAddCurveCompoLineTg( nOutlineId, dExtra, false) EgtCloseCurveCompo( nOutlineId) EgtMove( nOutlineId, dExtra * Z_AX()) local nSolidId = EgtSurfTmByRegionExtrusion( nProcLayerId, nOutlineId, - ( dHeight + dExtra) * Z_AX()) EgtTransform( nSolidId, frHdwFrame) EgtSurfTmSubtract( nMainExtrusionId, nSolidId) EgtErase( {nSolidId, nOutlineId}) end -- porto la lavorazione in globale EgtTransform( nPocketOutlineId, frHdwFrame) elseif vMacro[1] == 'TASCA' then elseif vMacro[1] == 'VITE' then local dRadius = 1.5 local dDepth = 2 if vMacro[2] == 'CANALINO' then dRadius = 2 dDepth = 3 elseif vMacro[2] == 'ANTA' then dRadius = 2.5 dDepth = 4 end local ptCenter = Point3d( dPosX, dPosY, dPosZ) local nHoleId = EgtCircle( nProcLayerId, ptCenter, dRadius) EgtModifyCurveExtrusion( nHoleId, Z_AX()) EgtModifyCurveThickness( nHoleId, - dDepth) EgtTransform( nHoleId, frHdwFrame) EgtSetInfo( nHoleId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE) elseif vMacro[1] == 'FORO' then local ptCenter = Point3d( dPosX, dPosY, dPosZ) local sDiameter = EgtReplaceString( vMacro[2], 'D', '') local dRadius = tonumber( sDiameter) / 2 local nHoleId = EgtCircle( nProcLayerId, ptCenter, dRadius) -- setto info di lavorazione EgtModifyCurveExtrusion( nHoleId, Z_AX()) local dDepth = tonumber(25) if #vMacro == 3 then dDepth = tonumber( vMacro[3]) end EgtModifyCurveThickness( nHoleId, - dDepth) EgtSetColor( nHoleId, EgtStdColor( 'GRAY')) EgtSetInfo( nHoleId, WIN_PRC_FEATURE_TYPE, WIN_PRC_TYPE.HOLE) -- aggiornamento del solido if s_bCalcSolid then local nSolidHoleId = EgtSurfTmByRegionExtrusion( nProcLayerId, nHoleId, - ( dDepth + 1) * Z_AX()) EgtMove( nSolidHoleId, Z_AX()) EgtTransform( nSolidHoleId, frHdwFrame) EgtSurfTmSubtract( nMainExtrusionId, nSolidHoleId) EgtErase( nSolidHoleId) end -- porto la lavorazione in globale EgtTransform( nHoleId, frHdwFrame) end end -- Chiudo file Output in lettura fhOutput:close() end -- funzione che aggiunge l'hardware function WinCalculate.AddHardware( nAreaId) -- verifico il tipo local nAreaType = EgtGetInfo( nAreaId, WIN_AREATYPE, 'i') local nSplitLayerId = EgtGetFirstNameInGroup( nAreaId, WIN_SPLIT) local nSplitType = WIN_SPLITTYPES.NULL if nSplitLayerId then nSplitType = EgtGetInfo( nSplitLayerId, WIN_SPLITTYPE, 'i') end if nAreaType == WIN_AREATYPES.SASH or ( nSplitLayerId and nSplitType == WIN_SPLITTYPES.FRENCH) then -- lancio calcolo sash WinCalculate.AddHardwareForSash( nAreaId) return else -- verifico se ci sono sotto-aree local nChildAreaId = EgtGetFirstNameInGroup( nAreaId, WIN_AREA .. '*') while nChildAreaId do -- lancio verifica di quell'area WinCalculate.AddHardware( nChildAreaId) nChildAreaId = EgtGetNextName( nChildAreaId, WIN_AREA .. '*') end end end --------------------------------------------------------------------- return WinCalculate