/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ var GMLL_xmargin = 2;; var GMLL_ymargin = 1;; struct MeasureLineLabel = [ MLL_label : VUIcontainer, MLL_textElement : VUIelement ] mkMeasureLineLabel;; struct MeasureLine = [ ML_Line : SO3_OBJECT, ML_iLineId : I, ML_XMLmark : XMLmark, ML_iNumPoints : I, ML_lPoses : [[F F F] r1], ML_lDistances : [F r1], ML_lAngles : [F r1], ML_lDistLabels : [MeasureLineLabel r1], ML_lAngleLabels : [MeasureLineLabel r1], ML_TrailingDistLabel : MeasureLineLabel, ML_TrailingAngleLabel : MeasureLineLabel, ML_TotalLengthLabel : MeasureLineLabel, ML_DeletionCross : VUIcontainer, ML_lHelpers : [SO3_OBJECT r1], ML_bShown : I ]mkMeasureLine;; struct PlugMeasureData = [ PMD_inst : PInstance, PMD_lLines : [MeasureLine r1], PMD_XMLfile : XMLfile, PMD_bAutosave : I, PMD_font : VUIfont, PMD_fsize : I, PMD_fcolor : I, PMD_bcolor : I, PMD_lcolor : I, PMD_helperMat : SO3_MATERIAL, PMD_lTouchPoints : [I r1], PMD_bTouchMode : I, PMD_fVisibilityDist : F, PMD_bAutoscale : I, PMD_fMaxAutoscaleDist : F, PMD_bTotalLength : I, PMD_bShowOnTop : I, PMD_bEnabled : I, PMD_bDrawing : I, PMD_bNeedAddPoint : I, PMD_iLastInputId : I ]mkPlugMeasureData;; var sMeasurePath = "tmp/measure/";; fun deleteLabelList(list)= while (list != nil) do ( let hd list -> labelstr in VUIdestroyContainer labelstr.MLL_label; set list = tl list; ); 0;; fun clearLine(obstr, linestr)= SO3ObjectDestroy linestr.ML_Line; set linestr.ML_Line = nil; deleteLabelList linestr.ML_lDistLabels; deleteLabelList linestr.ML_lAngleLabels; VUIdestroyContainer linestr.ML_TrailingDistLabel.MLL_label; VUIdestroyContainer linestr.ML_TrailingAngleLabel.MLL_label; VUIdestroyContainer linestr.ML_TotalLengthLabel.MLL_label; VUIdestroyContainer linestr.ML_DeletionCross; XMLdelMark obstr.PMD_XMLfile linestr.ML_XMLmark; while (linestr.ML_lHelpers != nil) do ( SO3ObjectDestroy hd linestr.ML_lHelpers; set linestr.ML_lHelpers = tl linestr.ML_lHelpers; ); 0;; fun deleteOb(inst, obstr)= set obstr.PMD_inst = nil; VUIdelFont obstr.PMD_font; while (obstr.PMD_lLines != nil) do ( clearLine obstr (hd obstr.PMD_lLines); set obstr.PMD_lLines = tl obstr.PMD_lLines; ); SO3MaterialDestroy obstr.PMD_helperMat; SO3GroupDelete (V3DgetSession c3dXsession) getPluginInstanceName inst; set obstr.PMD_bDrawing = 0; 0;; fun cbClearLastLine(inst, from, action, param, rep, obstr)= if (obstr.PMD_lLines == nil) then nil else ( clearLine obstr (hd obstr.PMD_lLines); set obstr.PMD_lLines = tl obstr.PMD_lLines; set obstr.PMD_bDrawing = 0; ); if (obstr.PMD_bAutosave == 0) then nil else XMLwrite obstr.PMD_XMLfile (strcatn sMeasurePath::(getPluginInstanceName inst)::".xml"::nil); 0;; fun cbClearAll(inst, from, action, param, rep, obstr)= while (obstr.PMD_lLines != nil) do ( clearLine obstr (hd obstr.PMD_lLines); set obstr.PMD_lLines = tl obstr.PMD_lLines; ); set obstr.PMD_bDrawing = 0; if (obstr.PMD_bAutosave == 0) then nil else XMLwrite obstr.PMD_XMLfile (strcatn sMeasurePath::(getPluginInstanceName inst)::".xml"::nil); 0;; fun unitSelector (dist)= if (dist <. 0.01) then strcat (ftoa2d dist *. 1000.0) " mm" else if (dist <. 1.0) then strcat (ftoa2d dist *. 100.0) " cm" else if (dist >=. 1000.0) then strcat (ftoa2d dist /. 1000.0) " km" else strcat (ftoa2d dist) " m";; fun getAngle(pos1, anglePoint, pos2)= let anglePoint -> [xa ya za] in let pos1 -> [x1 y1 z1] in let pos2 -> [x2 y2 z2] in let normalizeVectorF [(x1 -. xa) (y1 -. ya) (z1 -.za)] -> norm1 in let normalizeVectorF [(x2 -. xa) (y2 -. ya) (z2 -.za)] -> norm2 in SO3MathsRadianToDegree acos (dotVectorF norm1 norm2);; fun getDistance(pos1, pos2)= let pos1 -> [x1 y1 z1] in let pos2 -> [x2 y2 z2] in sqrt ((sqr(x1 -. x2)) +. (sqr(y1 -. y2)) +. (sqr(z1 -. z2)));; fun updateAllHelpers(obstr)= let V3DgetSessionView c3dXsession -> viewstr in let V3DgetDefaultViewport viewstr -> viewportstr in let V3DgetViewportSize viewstr viewportstr -> [_ _ _ vh] in let if (vh <= 0) then 1 else if (viewstr.V3D_bVRmode) then iVUIBASEVRHEIGHT else vh -> vh in let V3DgetViewportCamera viewportstr -> cam in let V3DgetOrthographicMode cam -> ortho in let if ortho then V3DgetOrthographicScale cam else 0.0 -> cscale in let if (viewstr.V3D_bVRmode) then SO3MathsDegreeToRadian iVUIBASEVRFOV else (SO3CameraGetFOVy cam) -> fovy in let if ((fovy <=. 0.0) || ortho) then 1.0 else fovy -> fovy in let SO3ObjectGetGlobalPosition cam -> campos in let SO3ObjectGetGlobalOrientation cam -> quat in let 80.0 -> scalecoef in let sizelist obstr.PMD_lLines -> size in let 0 -> i in while (i < size) do ( let nth_list obstr.PMD_lLines i -> linestr in let sizelist linestr.ML_lHelpers -> hsize in let sizelist linestr.ML_lDistLabels -> dsize in let sizelist linestr.ML_lAngleLabels -> asize in let 0 -> j in ( while (j < hsize) do ( let nth_list linestr.ML_lHelpers j -> helper in let SO3ObjectGetGlobalPosition helper -> ppos in let if (cscale != 0.0) then cscale *. scalecoef else if (viewstr.V3D_bVRmode) then (getVectorDistanceF campos ppos) *. scalecoef else let normalizeVectorF (SO3MathsQuatGetDirection quat [0.0 0.0 (-.1.0)]) -> dir in (dotVectorF (subVectorF ppos campos) dir) *. scalecoef -> dist in let maxf 0.000001 ((dist /. ((itof vh) /. 2.0)) *. fovy) /. 2.0 -> cdist in let if (viewstr.V3D_bVRmode) then 0.8 else 0.6 -> maxscale in let getVectorDistanceF campos ppos -> ccdist in let if ((obstr.PMD_fVisibilityDist != 0.0) && (ccdist >=. obstr.PMD_fVisibilityDist)) then 0 else 1 -> state in ( if (cdist >. maxscale) then SO3ObjectSetScale helper [maxscale maxscale maxscale] else SO3ObjectSetScale helper [cdist cdist cdist]; SO3ObjectSetVisible helper state 1; if (j == 0) then VUIset3DContainerVisible linestr.ML_DeletionCross (state && obstr.PMD_bEnabled) else if (j == hsize - 1) then VUIset3DContainerVisible linestr.ML_TotalLengthLabel.MLL_label (state && obstr.PMD_bTotalLength) else // angle labels visibility ( let nth_list linestr.ML_lAngleLabels (j - 1) -> labelstr in VUIset3DContainerVisible labelstr.MLL_label state; ); ); set j = j + 1; ); // distance labels visibility set j = 0; while (j < dsize) do ( let nth_list linestr.ML_lDistLabels j -> labelstr in let VUIget3DContainerPosition labelstr.MLL_label -> ppos in let getVectorDistanceF campos ppos -> ccdist in let if ((obstr.PMD_fVisibilityDist != 0.0) && (ccdist >=. obstr.PMD_fVisibilityDist)) then 0 else 1 -> state in ( VUIset3DContainerVisible labelstr.MLL_label state; SO3ObjectSetVisible linestr.ML_Line state 1; ); set j = j + 1; ); /* set j = 0; while (j < asize) do ( let nth_list linestr.ML_lAngleLabels j -> labelstr in let VUIget3DContainerPosition labelstr.MLL_label -> ppos in let getVectorDistanceF campos ppos -> ccdist in let if ((obstr.PMD_fVisibilityDist != 0.0) && (ccdist >=. obstr.PMD_fVisibilityDist)) then 0 else 1 -> state in ( VUIset3DContainerVisible labelstr.MLL_label state; ); set j = j + 1; ); */ ); set i = i + 1; ); 0;; fun addHelper(obstr, linestr, pos)= let getPluginInstanceName obstr.PMD_inst -> iname in let strcatn iname::".helper"::(itoa linestr.ML_iLineId)::"_"::(itoa sizelist linestr.ML_lHelpers)::nil -> helperName in let SO3OctahedronCreate (V3DgetSession c3dXsession) iname helperName 0.14 0.1 0.1 -> helper in ( SO3ObjectSetCastShadows helper 0; SO3ObjectSetMouseClick helper 0; SO3EntitySetMaterial helper obstr.PMD_helperMat 0; if (obstr.PMD_bShowOnTop == 0) then nil else ( SO3ObjectSetMouseForeGround helper 1; SO3ObjectSetRenderOverlay helper 1; ); SO3ObjectSetPosition helper pos; set linestr.ML_lHelpers = helper::linestr.ML_lHelpers; ); 0;; fun cbDelButton(eltstr, id, x, y, btn, p)= let p -> [obstr linestr] in ( set obstr.PMD_lLines = remove_from_list obstr.PMD_lLines linestr; clearLine obstr linestr; if (obstr.PMD_bAutosave == 0) then nil else XMLwrite obstr.PMD_XMLfile (strcatn sMeasurePath::(getPluginInstanceName obstr.PMD_inst)::".xml"::nil); ); 0;; fun createDelButton(obstr, linestr)= let SO3ObjectGetGlobalPosition (hd linestr.ML_lHelpers) -> pos in set linestr.ML_DeletionCross = VUIcreate3dContainer c3dXsession obstr.PMD_inst.INST_groupstr.GRP_project.PRJ_vuiGroup pos [0.5 0.5] [20.0 20.0] 1.0 obstr.PMD_bAutoscale obstr.PMD_fMaxAutoscaleDist 1 100 obstr.PMD_bShowOnTop; let VUIcreateButton linestr.ML_DeletionCross nil [0.0 0.0] [16.0 16.0] [0 0 0 0 0 0 0 0] [1 1] -> delbtn in let strcat (getPluginDirectory (getInstancePlugin obstr.PMD_inst)) "/res/closebtn.png" -> btnpath in ( VUIsetContainerBackground linestr.ML_DeletionCross nil nil nil nil nil 0 1 0; VUIsetElementResource delbtn nil nil nil (_checkpack btnpath) nil nil nil nil nil; VUIsetElementCbClick delbtn mkfun6 @cbDelButton [obstr linestr]; VUIshowContainer linestr.ML_DeletionCross 1; ); 0;; fun createTotalLengthLabel(obstr, linestr)= if linestr.ML_iNumPoints <= 2 then nil else let nth_list linestr.ML_lPoses (linestr.ML_iNumPoints - 1) -> pos in let VUIcreate3dContainer c3dXsession obstr.PMD_inst.INST_groupstr.GRP_project.PRJ_vuiGroup pos [0.5 0.5] [16.0 16.0] 1.0 obstr.PMD_bAutoscale obstr.PMD_fMaxAutoscaleDist 1 100 obstr.PMD_bShowOnTop -> newLabel in let VUIcreateFrame newLabel nil [0.0 0.0] [100.0 100.0] [0 0 1 1 0 0 0 0] [1 1] -> textElement in let 0.0 -> totalLength in ( VUIsetContainerBackground newLabel obstr.PMD_bcolor nil nil nil nil 0 1 0; VUIsetContainerInputsEnable newLabel 0; VUIsetElementText textElement VUIcreateFontInterface obstr.PMD_font " " [0 0] [0 0] [GMLL_xmargin GMLL_ymargin] iVUITEXT_HALIGNCENTER|iVUITEXT_VALIGNCENTER VUI_TextAuto 0; //VUIsetElementResource textElement obstr.PMD_bcolor nil nil nil nil nil nil nil nil; let sizelist linestr.ML_lDistances -> size in let 0 -> i in while (i < size) do ( let nth_list linestr.ML_lDistances i -> length in set totalLength = totalLength +. length; set i = i + 1; ); let strcat "Total: " (unitSelector totalLength) -> text in let VUIgetTextSize obstr.PMD_font text 0 iVUITEXT_HALIGNCENTER|iVUITEXT_VALIGNCENTER -> [tw th] in ( VUIsetElementTextContent textElement text; VUIsetContainerSize newLabel [(itof (tw + 2 * GMLL_xmargin)) (itof (th + 2 * GMLL_ymargin))] nil; ); set linestr.ML_TotalLengthLabel = mkMeasureLineLabel[newLabel textElement]; VUIset3dContainerMouseState newLabel 0; VUIshowContainer newLabel 1; ); 0;; fun addLineToXML(obstr, linestr)= let XMLgetMarkByValue obstr.PMD_XMLfile "measure" -> measuremark in let XMLaddMark obstr.PMD_XMLfile "line" measuremark nil nil -> linemark in ( set linestr.ML_XMLmark = linemark; let sizelist linestr.ML_lPoses -> size in let 0 -> i in while (i < size) do { let nth_list linestr.ML_lPoses i -> point in let point -> [x y z] in XMLaddMark obstr.PMD_XMLfile "point" linemark ["X" (ftoa x)]::["Y" (ftoa y)]::["Z" (ftoa z)]::nil nil; set i = i + 1; }; ); if (obstr.PMD_bAutosave == 0) then nil else XMLwrite obstr.PMD_XMLfile (strcatn sMeasurePath::(getPluginInstanceName obstr.PMD_inst)::".xml"::nil); 0;; fun cancelPoint(obstr, linestr)= if (obstr.PMD_bTouchMode) then nil else SO3LineEntityRemovePoint linestr.ML_Line nil; VUIdestroyContainer linestr.ML_TrailingDistLabel.MLL_label; VUIdestroyContainer linestr.ML_TrailingAngleLabel.MLL_label; if (linestr.ML_iNumPoints > 1) then ( createDelButton obstr linestr; createTotalLengthLabel obstr linestr; if (obstr.PMD_bTotalLength) then nil else VUIset3DContainerVisible linestr.ML_TotalLengthLabel.MLL_label 0; addLineToXML obstr linestr; ) else cbClearLastLine nil nil nil nil nil obstr; 0;; fun createLabel(obstr, pos, offset)= let V3DgetSessionView c3dXsession -> viewstr in let VUIcreate3dContainer c3dXsession obstr.PMD_inst.INST_groupstr.GRP_project.PRJ_vuiGroup pos offset [16.0 16.0] 1.0 obstr.PMD_bAutoscale obstr.PMD_fMaxAutoscaleDist 1 100 obstr.PMD_bShowOnTop -> newLabel in let VUIcreateFrame newLabel nil [0.0 0.0] [100.0 100.0] [0 0 1 1 0 0 0 0] [1 1] -> textElement in ( VUIsetContainerBackground newLabel obstr.PMD_bcolor nil nil nil nil 0 1 0; VUIsetContainerInputsEnable newLabel 0; VUIsetElementText textElement VUIcreateFontInterface obstr.PMD_font " " [0 0] [0 0] [GMLL_xmargin GMLL_ymargin] iVUITEXT_HALIGNCENTER|iVUITEXT_VALIGNCENTER VUI_TextAuto 0; //VUIsetElementResource textElement obstr.PMD_bcolor nil nil nil nil nil nil nil nil; VUIset3dContainerMouseState newLabel 0; VUIshowContainer newLabel 1; mkMeasureLineLabel[newLabel textElement]; );; fun addPointData(obstr, linestr, pos)= set linestr.ML_lPoses = pos::linestr.ML_lPoses; set linestr.ML_iNumPoints = sizelist linestr.ML_lPoses; //Distance and distance label if linestr.ML_iNumPoints < 2 then nil else let (getDistance (hd linestr.ML_lPoses) (hd tl linestr.ML_lPoses)) -> dist in let (multiplyVectorF (addVectorF pos hd tl linestr.ML_lPoses) [0.5 0.5 0.5]) -> distlabelpos in let createLabel obstr distlabelpos [0.0 0.0] -> newdistlabel in let unitSelector dist -> text in ( VUIsetElementTextContent newdistlabel.MLL_textElement text; let VUIgetTextSize obstr.PMD_font text 0 iVUITEXT_HALIGNCENTER|iVUITEXT_VALIGNCENTER -> [tw th] in VUIsetContainerSize newdistlabel.MLL_label [(itof (tw + 2 * GMLL_xmargin)) (itof (th + 2 * GMLL_ymargin))] nil; set linestr.ML_lDistLabels = newdistlabel::linestr.ML_lDistLabels; set linestr.ML_lDistances = dist::linestr.ML_lDistances; ); //create new angle label if linestr.ML_iNumPoints < 3 then nil else let (getAngle (hd tl tl linestr.ML_lPoses) (hd tl linestr.ML_lPoses) (hd linestr.ML_lPoses)) -> angle in let createLabel obstr (hd tl linestr.ML_lPoses) [0.6 0.5] -> newanglelabel in let (strcat ftoa2d angle " deg") -> text in ( VUIsetElementTextContent newanglelabel.MLL_textElement text; let VUIgetTextSize obstr.PMD_font text 0 iVUITEXT_HALIGNCENTER|iVUITEXT_VALIGNCENTER -> [tw th] in VUIsetContainerSize newanglelabel.MLL_label [(itof (tw + 2 * GMLL_xmargin)) (itof (th + 2 * GMLL_ymargin))] nil; set linestr.ML_lAngleLabels = newanglelabel::linestr.ML_lAngleLabels; set linestr.ML_lAngles = angle::linestr.ML_lAngles; ); //add a helper on the clicked pos addHelper obstr linestr pos; 0;; fun addPoint(obstr, linestr, pos)= if vectorEqualF pos hd linestr.ML_lPoses then nil else ( //add position to list, add labels, helper and compute data for the added point addPointData obstr linestr pos; //create line or set/add new point if (linestr.ML_Line == nil) then ( let getPluginInstanceName obstr.PMD_inst -> instname in let strcatn instname::"_measure_"::(itoa linestr.ML_iLineId)::nil -> linestrname in set linestr.ML_Line = SO3LineEntityCreateEx (V3DgetSession c3dXsession) linestrname linestr.ML_lPoses G2Drgb2rgba obstr.PMD_lcolor 128 obstr.PMD_bShowOnTop; SO3ObjectSetMouseClick linestr.ML_Line 0; 0; ) else ( if (obstr.PMD_bTouchMode) then SO3LineEntityAddPoint linestr.ML_Line nil pos else ( SO3LineEntitySetPoint linestr.ML_Line nil pos; SO3LineEntityAddPoint linestr.ML_Line nil pos ); 0; ); ); 0;; fun getDrawnLine(obstr)= let nil -> linestr in let sizelist obstr.PMD_lLines -> size in let 0 -> i in let 0 -> found in if (obstr.PMD_bDrawing == 0) then nil else ( while (i <= size && found != 1) do ( set linestr = nth_list obstr.PMD_lLines i; if (linestr.ML_iLineId != obstr.PMD_bDrawing) then nil else set found = 1; set i = i + 1; ); linestr; );; fun cbPreRender(inst, viewstr, obstr)= let V3DgetLastMouseData viewstr obstr.PMD_iLastInputId -> [_ _ obj _ _ _ dvec _ _] in let getDrawnLine obstr -> linestr in //necessary in case a new measure is inserted with cbAddMeasure while drawing let SO3ObjectGetFlags obj -> obflag in if ((obj == nil) || (dvec == nil) || (obflag & iNodeFlagController) || (obflag & iNodeFlagVUI) || (obflag & iNodeFlagTools)) then nil else ( //add point on click if (!obstr.PMD_bNeedAddPoint) then nil else ( addPoint obstr (hd obstr.PMD_lLines) dvec; set obstr.PMD_bNeedAddPoint = 0; ); //add or remove the labels following the mouse if control is mouse or touch if (!obstr.PMD_bTouchMode || (linestr.ML_TrailingDistLabel == nil)) then nil else ( SO3LineEntityRemovePoint linestr.ML_Line nil; VUIdestroyContainer linestr.ML_TrailingDistLabel.MLL_label; VUIdestroyContainer linestr.ML_TrailingAngleLabel.MLL_label; set linestr.ML_TrailingDistLabel = nil; set linestr.ML_TrailingAngleLabel = nil; ); if (obstr.PMD_bTouchMode || (linestr.ML_TrailingDistLabel != nil) || !obstr.PMD_bDrawing) then nil else ( if (linestr.ML_iNumPoints < 2) then nil else set linestr.ML_TrailingAngleLabel = createLabel obstr hd linestr.ML_lPoses [0.6 0.5]; set linestr.ML_TrailingDistLabel = createLabel obstr dvec [0.6 0.5]; SO3LineEntityAddPoint linestr.ML_Line nil dvec; ); //update labels following the mouse if ((!obstr.PMD_bDrawing || obstr.PMD_bTouchMode)) then nil else // point and label following mouse position update ( if (linestr.ML_iNumPoints < 1) then nil else ( SO3LineEntitySetPoint linestr.ML_Line nil dvec; if (linestr.ML_iNumPoints < 1) then nil else let getDistance dvec (hd linestr.ML_lPoses) -> dist in ( SendPluginEvent inst "Current Distance" ftoa dist nil; VUIset3DContainerPosition linestr.ML_TrailingDistLabel.MLL_label dvec; VUIsetElementTextContent linestr.ML_TrailingDistLabel.MLL_textElement (unitSelector dist); let linestr.ML_TrailingDistLabel.MLL_textElement.VUIE_Text.VUIT_tTextSize -> [tw th] in VUIsetContainerSize linestr.ML_TrailingDistLabel.MLL_label [(itof (tw + 2 * GMLL_xmargin)) (itof (th + 2 * GMLL_ymargin))] nil; 0; ); if (linestr.ML_iNumPoints < 2) then nil else let getAngle (hd tl linestr.ML_lPoses) (hd linestr.ML_lPoses) dvec -> angle in ( SendPluginEvent inst "Current Angle" ftoa angle nil; VUIsetElementTextContent linestr.ML_TrailingAngleLabel.MLL_textElement (strcat ftoa2d angle " deg"); let linestr.ML_TrailingAngleLabel.MLL_textElement.VUIE_Text.VUIT_tTextSize -> [tw th] in VUIsetContainerSize linestr.ML_TrailingAngleLabel.MLL_label [(itof (tw + 2 * GMLL_xmargin)) (itof (th + 2 * GMLL_ymargin))] nil; ); ); ); ); //all helpers scale update updateAllHelpers obstr; 0;; fun cbInputClick(inst, viewstr, id, x, y, btn, pdata, obstr)= let pdata -> [obj _ _ dvec _ _] in let SO3ObjectGetFlags obj -> obflag in if ((obj == nil) || (dvec == nil) || (obflag & iNodeFlagController) || (obflag & iNodeFlagVUI) || (obflag & iNodeFlagTools)) then nil else ( if (btn == 1) then //leftClick ( if obstr.PMD_bDrawing != 0 then nil else ( let hd obstr.PMD_lLines -> linestr in let if linestr == nil then 1 else linestr.ML_iLineId + 1 -> nid in ( set obstr.PMD_lLines = (mkMeasureLine [nil nid nil 0 nil nil nil nil nil nil nil nil nil nil 1]) :: obstr.PMD_lLines; set obstr.PMD_bDrawing = nid; ); 0; ); set obstr.PMD_bNeedAddPoint = 1; set obstr.PMD_iLastInputId = id; 0; ) else nil; ); //allow to cancel even if the mouse position is outside the model if (btn == 2) && (obstr.PMD_bDrawing != 0) then //RightClick ( set obstr.PMD_bDrawing = 0; cancelPoint obstr hd obstr.PMD_lLines; SendPluginEvent inst "Measure ended" nil nil; 0; ) else nil; 0;; fun cbInputUpdate(inst, viewstr, id, x, y, btn, pdata, obstr)= if (id != 0) then nil else if (obstr.PMD_lTouchPoints != nil) || !obstr.PMD_bTouchMode then nil else ( set obstr.PMD_bTouchMode = 0; ); 0;; fun cbAddCursor(inst, viewstr, id, x, y, obstr)= set obstr.PMD_lTouchPoints = id::obstr.PMD_lTouchPoints; set obstr.PMD_bTouchMode = 1; 0;; fun cbRemoveCursor(inst, viewstr, id, obstr)= set obstr.PMD_lTouchPoints = remove_from_list obstr.PMD_lTouchPoints id; 0;; fun cbShow(inst, from, action, param, rep, obstr)= setPluginInstanceCbPreRender inst mkfun3 @cbPreRender obstr; let sizelist obstr.PMD_lLines -> size in let 0 -> i in while (i < size) do ( let nth_list obstr.PMD_lLines i -> linestr in let getPluginInstanceName obstr.PMD_inst -> instname in let strcatn instname::"_measure_"::(itoa size - 1 - i)::nil -> linestrname in ( if (linestr.ML_bShown == 1) then nil else ( if (linestr.ML_Line != nil) then nil else set linestr.ML_Line = SO3LineEntityCreateEx (V3DgetSession c3dXsession) linestrname linestr.ML_lPoses G2Drgb2rgba obstr.PMD_lcolor 128 obstr.PMD_bShowOnTop; SO3ObjectSetMouseClick linestr.ML_Line 0; let sizelist linestr.ML_lDistLabels -> dsize in let sizelist linestr.ML_lAngleLabels -> asize in let sizelist linestr.ML_lHelpers -> hsize in let 0 -> j in ( while (j < dsize) do ( let nth_list linestr.ML_lDistLabels j -> labelstr in VUIset3DContainerVisible labelstr.MLL_label 1; set j = j + 1; ); set j = 0; while (j < asize) do ( let nth_list linestr.ML_lAngleLabels j -> labelstr in VUIset3DContainerVisible labelstr.MLL_label 1; set j = j + 1; ); set j = 0; while (j < hsize) do ( SO3ObjectSetVisible nth_list linestr.ML_lHelpers j 1 1; set j = j + 1; ); ); if (!obstr.PMD_bEnabled) then nil else VUIset3DContainerVisible linestr.ML_DeletionCross 1; if (!obstr.PMD_bTotalLength) then nil else VUIset3DContainerVisible linestr.ML_TotalLengthLabel.MLL_label 1; set linestr.ML_bShown = 1; ); ); set i = i + 1; ); 0;; fun cbEnable(inst, from, action, param, rep, obstr)= if (obstr.PMD_bEnabled) then nil else ( setPluginInstanceCbTouchPointAdd inst mkfun6 @cbAddCursor obstr; setPluginInstanceCbTouchPointRemove inst mkfun4 @cbRemoveCursor obstr; setPluginInstanceCbInputUpdate inst mkfun8 @cbInputUpdate obstr; setPluginInstanceCbInputClick inst mkfun8 @cbInputClick obstr; //if (obstr.PMD_bShown == 1) then nil else //cbShow inst nil nil nil nil obstr; let sizelist obstr.PMD_lLines -> size in let 0 -> i in while (i < size) do ( let nth_list obstr.PMD_lLines i -> linestr in if (!linestr.ML_bShown) then nil else VUIset3DContainerVisible linestr.ML_DeletionCross 1; set i = i + 1; ); SendPluginEvent inst "Enabled" nil nil; set obstr.PMD_bEnabled = 1; ); 0;; fun cbDisable(inst, from, action, param, rep, obstr)= if obstr.PMD_bDrawing == 0 then nil else ( cancelPoint obstr hd obstr.PMD_lLines; set obstr.PMD_bDrawing = 0; ); setPluginInstanceCbTouchPointAdd inst nil; setPluginInstanceCbTouchPointRemove inst nil; setPluginInstanceCbInputUpdate inst nil; setPluginInstanceCbInputClick inst nil; let sizelist obstr.PMD_lLines -> size in let 0 -> i in while (i < size) do ( let nth_list obstr.PMD_lLines i -> linestr in VUIset3DContainerVisible linestr.ML_DeletionCross 0; set i = i + 1; ); SendPluginEvent inst "Disabled" nil nil; set obstr.PMD_bEnabled = 0; 0;; fun cbHide(inst, from, action, param, rep, obstr)= //cbDisable inst nil nil nil nil obstr; setPluginInstanceCbPreRender inst nil; if obstr.PMD_bDrawing == 0 then nil else ( cancelPoint obstr hd obstr.PMD_lLines; set obstr.PMD_bDrawing = 0; ); let sizelist obstr.PMD_lLines -> size in let 0 -> i in while (i < size) do ( let nth_list obstr.PMD_lLines i -> linestr in ( if (linestr.ML_bShown == 0) then nil else ( SO3ObjectDestroy linestr.ML_Line; set linestr.ML_Line = nil; let sizelist linestr.ML_lDistLabels -> dsize in let sizelist linestr.ML_lAngleLabels -> asize in let sizelist linestr.ML_lHelpers -> hsize in let 0 -> j in ( while (j < dsize) do ( let nth_list linestr.ML_lDistLabels j -> labelstr in VUIset3DContainerVisible labelstr.MLL_label 0; set j = j + 1; ); set j = 0; while (j < asize) do ( let nth_list linestr.ML_lAngleLabels j -> labelstr in VUIset3DContainerVisible labelstr.MLL_label 0; set j = j + 1; ); set j = 0; while (j < hsize) do ( SO3ObjectSetVisible nth_list linestr.ML_lHelpers j 0 1; set j = j + 1; ); ); ); VUIset3DContainerVisible linestr.ML_DeletionCross 0; set linestr.ML_bShown = 0; ); set i = i + 1; ); 0;; fun cbAddMeasure(inst, from, action, param, rep, obstr)= let nil -> lposes in ( if (!strcmp "" (strtrim param)) || param == nil then nil else ( let strextr param -> lp in while (lp != nil) do ( set lposes = [(atof (nth_list (hd lp) 0)) (atof (nth_list (hd lp) 1)) (atof (nth_list (hd lp) 2))]::lposes; set lp = tl lp; ); ); if (sizelist lposes) < 2 then nil else ( let hd obstr.PMD_lLines -> prevlinestr in let if prevlinestr == nil then 1 else prevlinestr.ML_iLineId + 1 -> id in let (mkMeasureLine [nil id nil 0 nil nil nil nil nil nil nil nil nil nil 1]) -> linestr in ( while (lposes != nil) do ( //add position to list, add labels, helper and compute data for the added point addPointData obstr linestr (hd lposes); set lposes = tl lposes; ); let getPluginInstanceName obstr.PMD_inst -> instname in let strcatn instname::"_measure_"::(itoa linestr.ML_iLineId)::nil -> linestrname in set linestr.ML_Line = SO3LineEntityCreateEx (V3DgetSession c3dXsession) linestrname linestr.ML_lPoses G2Drgb2rgba obstr.PMD_lcolor 128 obstr.PMD_bShowOnTop; set obstr.PMD_lLines = linestr::obstr.PMD_lLines; createDelButton obstr linestr; createTotalLengthLabel obstr linestr; addLineToXML obstr linestr; ); ); ); 0;; fun cbSave(inst, from, action, param, reply, obstr)= XMLwrite obstr.PMD_XMLfile (strcatn sMeasurePath::(getPluginInstanceName inst)::".xml"::nil); 0;; fun loadLine(obstr, linestr)= let revertlist (XMLgetMarksByValueFromMarkSons linestr.ML_XMLmark "point") -> pointmarks in while (pointmarks != nil) do ( let hd pointmarks -> pointmark in let [atof(XMLgetParam pointmark "X") atof(XMLgetParam pointmark "Y") atof(XMLgetParam pointmark "Z")] -> pos in ( //add position to list, add labels, helper and compute data for the added point addPointData obstr linestr pos; ); set pointmarks = tl pointmarks; ); let getPluginInstanceName obstr.PMD_inst -> instname in let strcatn instname::"_measure_"::(itoa linestr.ML_iLineId)::nil -> linestrname in set linestr.ML_Line = SO3LineEntityCreateEx (V3DgetSession c3dXsession) linestrname linestr.ML_lPoses G2Drgb2rgba obstr.PMD_lcolor 128 obstr.PMD_bShowOnTop; SO3ObjectSetMouseClick linestr.ML_Line 0; createDelButton obstr linestr; createTotalLengthLabel obstr linestr; VUIset3DContainerVisible linestr.ML_DeletionCross 0; if (!obstr.PMD_bTotalLength) then VUIset3DContainerVisible linestr.ML_TotalLengthLabel.MLL_label 0 else VUIset3DContainerVisible linestr.ML_TotalLengthLabel.MLL_label 1; 0;; fun loadMeasures(obstr)= if (obstr.PMD_XMLfile == nil) then nil else ( let XMLgetMarkByValue obstr.PMD_XMLfile "measure" -> measuremark in let if measuremark != nil then measuremark else XMLaddMark obstr.PMD_XMLfile "measure" nil nil nil -> measuremark in let XMLgetMarksByValueFromMarkSons measuremark "line" -> linemarks in let sizelist linemarks -> size in let 0 -> i in while (i < size) do ( let nth_list linemarks i -> linemark in let mkMeasureLine [nil (i + 1) linemark 0 nil nil nil nil nil nil nil nil nil nil 1] -> linestr in ( loadLine obstr linestr; set obstr.PMD_lLines = linestr::obstr.PMD_lLines; ); set i = i + 1; ); ); 0;; fun newOb(inst)= let atoi (getPluginInstanceParam inst "fontsize") -> fsize in let if fsize == nil then 9 else fsize -> fsize in let atoi (getPluginInstanceParam inst "fontcolor") -> fcolor in let if fcolor == nil then 0xffffff else fcolor -> fcolor in let atoi (getPluginInstanceParam inst "backgroundcolor") -> bcolor in let if bcolor == nil then 64 else bcolor -> bcolor in let atoi (getPluginInstanceParam inst "linecolor") -> lcolor in let if lcolor == nil then 0x0000ff else lcolor -> lcolor in let atof (getPluginInstanceParam inst "visibility") -> visibility in let if visibility == nil then 0.0 else visibility -> visibility in let atoi (getPluginInstanceParam inst "autoscale") -> autoscale in let if autoscale == nil then 1 else autoscale -> autoscale in let atof (getPluginInstanceParam inst "maxautoscaledist") -> maxautoscaledist in let if maxautoscaledist == nil then 10.0 else maxautoscaledist -> maxautoscaledist in let atoi (getPluginInstanceParam inst "totallength") -> totallength in let if totallength == nil then 0 else totallength -> totallength in let atoi (getPluginInstanceParam inst "autosave") -> autosave in let if autosave == nil then 0 else autosave -> autosave in let atoi (getPluginInstanceParam inst "show") -> show in let if show == nil then 1 else show -> show in let atoi (getPluginInstanceParam inst "ontop") -> ontop in let if ontop == nil then 1 else ontop -> ontop in let atoi (getPluginInstanceParam inst "init") -> init in let if init == nil then 1 else init -> init in let VUIcreateFont "Sans" fsize iVUITEXT_BOLD fcolor 1 -> font in let getPluginInstanceName inst -> iname in let strcatn sMeasurePath::iname::".xml"::nil -> filepath in let XMLload filepath -> xmlfile in let if xmlfile != nil then xmlfile else (XMLwrite nil filepath; XMLload filepath;) -> xmlfile in let mkPlugMeasureData[inst nil xmlfile autosave font fsize fcolor bcolor lcolor nil nil 0 visibility autoscale maxautoscaledist totallength ontop 0 0 0 0] -> obstr in ( SO3GroupCreate (V3DgetSession c3dXsession) iname; let SO3MaterialCreate (V3DgetSession c3dXsession) (strcat iname ".material") iname -> mat in ( set obstr.PMD_helperMat = mat; SO3MaterialSetReceiveShadows mat 0; SO3MaterialSetIgnoreSlicePlane mat 1; if (obstr.PMD_bShowOnTop == 0) then nil else ( SO3MaterialSetPassDepthFunction mat 0 0 SO3_COMPARE_FUNCTION_ALWAYS_PASS; SO3MaterialSetPassDepthWriteEnabled mat 0 0 0; ); SO3MaterialSetAmbient mat (G2Drgb2rgba obstr.PMD_lcolor 128); SO3MaterialSetDiffuse mat (G2Drgb2rgba obstr.PMD_lcolor 128); SO3MaterialSetSelfIllumination mat (G2Drgb2rgba obstr.PMD_lcolor 128); SO3MaterialSetSpecular mat (G2Drgb2rgba obstr.PMD_lcolor 128); SO3MaterialSetShininess mat 128.0; ); loadMeasures obstr; setPluginInstanceCbPreRender inst mkfun3 @cbPreRender obstr; if (show) then nil else cbHide inst nil nil nil nil obstr; if (!init) then nil else cbEnable inst nil nil nil nil obstr; PluginRegisterAction inst "Enable" mkfun6 @cbEnable obstr; PluginRegisterAction inst "Disable" mkfun6 @cbDisable obstr; PluginRegisterAction inst "Show" mkfun6 @cbShow obstr; PluginRegisterAction inst "Add measure" mkfun6 @cbAddMeasure obstr; PluginRegisterAction inst "Hide" mkfun6 @cbHide obstr; PluginRegisterAction inst "Clear all" mkfun6 @cbClearAll obstr; PluginRegisterAction inst "Clear last line" mkfun6 @cbClearLastLine obstr; PluginRegisterAction inst "Save" mkfun6 @cbSave obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 0;; fun IniPlug(file)= VUIsetEnable c3dXsession 1; PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;