BillW Posted February 20, 2023 Share Posted February 20, 2023 This is driving me nuts. In the example file I have the following: Layer 0 set to elevation 0mm Layer 6000 set to elevation 6000mm On each layer, I have an extrude which I used to place 3D symbols (each containing a single 3D locus) and 3D plugins via the auto working plane option (\) The script palette has a script which tests the 3D location (ie getsymloc3D) of the selected object. When run on Layer 0 everything works fine. When I run on Layer 6000 I get weird results shown in the message box. I've tested the 3D symbols and plugin to see if they are planar which is not the case. I have tested on VW 2023 sp3, 2022 sp6, 2021 sp4 and 2020 sp6 (the attached file version). I can get a correct result on the 3D symbols via Get3DCentr which is fine for a single 3D locus but not for complex content. I understand if I got a correct result I would have to modify the Z value by the layer elevation base height. Any thoughts and whether I've got something wrong. TIA sympio baselev test.vwx Quote Link to comment
JBenghiat Posted February 21, 2023 Share Posted February 21, 2023 Two things are happening: 1. Your drawing is not as accurate as you think it is. Change your units to a decimal precision of .001, and you'll see that your extrude dimensions are rounding to the nearest mm in Obj Info. 2. GetSymLoc3D is getting the translation of the symbol's transformation matrix. For objects with a 3D rotation, this seems to take the layer elevation into account. For unrotated objects, it does not. That could possibly be a bug. In order to get the correct location: - Use GetSymLoc3D() for the z only. Use GetSymLoc() for the x and y - Use Get3DOrientation to get the axes rotations. If the x or y is non-zero, the z will have the layer elevation included in the value. Adjust accordingly. 1 Quote Link to comment
BillW Posted February 21, 2023 Author Share Posted February 21, 2023 Thanks. Nice bit of lateral thinking. I also understood the symbol's transformation matrix was used but not the solution. As you say the layer elevation is taken into account which saves a bit of code. Already got the symbol rotations covered as suggested. This is added to the various workarounds in the memory bank. Quote Link to comment
BillW Posted February 21, 2023 Author Share Posted February 21, 2023 Just when I thought I would have an answer to the problem I am finding the returned Z values differ depending on the type of object and rotations. The 3D locus returns Z height related to the active layer plane while the others are related to world base level (either correct or incorrect values). See attached image for values of rotation ie 0/0/0 and Z values returned (rounded). Something is not quite right. I am trying to align a new object (created at 0/0) ie 3D symbol or plugin with an existing object. I still have to modify the Z height by the layer base height to move new object into the correct location. I added 2D rectangle as the last example for a 2D planar object. Any guidance would be gratefully received. The code for the script is show below procedure test; Var planarset,btest,isMirroredXY : BOOLEAN; v1,rot : VECTOR; x,y,z : REAL; refID : LONGINT; baseElev, thickness : REAL; srcobjH : HANDLE; begin GetLayerElevation(actlayer, baseElev, thickness); srcobjH := fsactlayer; if gettypeN(srcobjH) = 9 then begin {3D locus} getlocus3D(srcobjH,v1.x,v1.y,v1.z); end else if gettypeN(srcobjH) = 3 then begin {2D rectangle} hcenter(srcobjH,x,y); refID := GetPlanarRef(srcobjH); btest := PlanarPtTo3DModelPt(refID,x,y,v1.x,v1.y,v1.z); btest := GetEntityMatrix(srcobjH,x,y,z,rot.x,rot.y,rot.z); {rot Z is the plane rotation not the objects} end else begin planarset := getObjectVariableBoolean(srcobjH,1161); if planarset then begin {2D symbol} getsymloc(srcobjH,x,y); refID := GetPlanarRef(srcobjH); btest := PlanarPtTo3DModelPt(refID,x,y,v1.x,v1.y,v1.z); btest := Get3DOrientation(srcobjH,rot.x,rot.y,rot.z,isMirroredXY); end else begin {3D symbol or plugin} getsymloc3D(srcobjH,v1.x,v1.y,v1.z); getsymloc(srcobjH,v1.x,v1.y); btest := Get3DOrientation(srcobjH,rot.x,rot.y,rot.z,isMirroredXY); end; end; message(planarset,' ',v1,' ',rot,' elev ',baseElev); end; run(test); convertsymleveltest v2.vwx Quote Link to comment
MullinRJ Posted February 22, 2023 Share Posted February 22, 2023 @BillW, Welcome to the world of 3D programming in VW. I'm guessing it's not what you were hoping for. In looking at your file, code, and the numbers you've posted, I can tell you many of them, if not most of them, are right. Since I have to get up early tomorrow, I don't have the luxury of really digging into your code. I think you're close, but you have to move very carefully, as you've already figured out, because small changes can have profound effects on the numbers presented. Also, you have to test every one of you assumptions carefully. If you still haven't resolved this by tomorrow when I get back, I'll jump back in. I spent the better part of a summer decoding the way the Entity Matrix was constructed for 2D shapes. I've tried to forget, but that hasn't happened completely yet. I can tell you the EM is employed the same for all 2D objects, EXCEPT for Symbols and Bitmap Images – and possibly PIOs (that part's foggy). Nice job so far, Raymond Quote Link to comment
BillW Posted February 22, 2023 Author Share Posted February 22, 2023 Thanks Raymond. Indeed 2D shapes (ie 2D rectangle) are a problem which I havent satisfactorily sorted out (cant handle 3D rotations of object plane). All other entities I think I have sorted out - see attached VW file and run script "align new 3D symbol" on each object type to align a new 3D symbol with the source object. Hope file will be usefull for others. I will need to tidy up code later. 3D programming in VW is really painfull as you say and I'm definitely not a novice. In the past, I have avoided/skirted around getting to grips with the full planar/3D interface, even limiting the scope of work. The script code is below procedure test; Var planarset,btest,isMirroredXY : BOOLEAN; v1,rot : VECTOR; x,y,z,cx,cy : REAL; refID : LONGINT; baseElev, thickness : REAL; srcobjH,symH : HANDLE; objty : INTEGER; begin GetLayerElevation(actlayer, baseElev, thickness); srcobjH := fsactlayer; objty := gettypeN(srcobjH); planarset := getObjectVariableBoolean(srcobjH,1161); dselectall; if objty = 9 then begin {3D locus} getlocus3D(srcobjH,v1.x,v1.y,v1.z); v1.z := v1.z+baseElev; symbol('3D axes',v1.x,v1.y,0); symH := Lnewobj; move3Dobj(symH,0,0,v1.z); end else if objty = 17 then begin {2D locus} getlocpt(srcobjH,x,y); refID := GetPlanarRef(srcobjH); btest := PlanarPtTo3DModelPt(refID,x,y,v1.x,v1.y,v1.z); btest := GetEntityMatrix(srcobjH,x,y,z,rot.x,rot.y,rot.z); symbol('3D axes',0,v1.y,0); symH := Lnewobj; move3Dobj(symH,0,0,v1.z); set3DRot(symH,rot.x,rot.y,rot.z,v1.x,v1.y,v1.z-baseElev); end else if objty = 3 then begin {2D rectangle} hcenter(srcobjH,cx,cy); { refID := GetPlanarRef(srcobjH); btest := PlanarPtTo3DModelPt(refID,x,y,v1.x,v1.y,v1.z); } btest := GetEntityMatrix(srcobjH,x,y,z,rot.x,rot.y,rot.z); v1.x := cx; v1.y := cy; v1.z := z; symbol('3D axes',0,v1.y,0); symH := Lnewobj; move3Dobj(symH,0,0,v1.z); set3DRot(symH,rot.x,rot.y,rot.z,v1.x,v1.y,v1.z-baseElev); end else begin if planarset then begin {2D symbol} btest := GetEntityMatrix(srcobjH,v1.x,v1.y,v1.z,rot.x,rot.y,rot.z); symbol('3D axes',v1.x,v1.y,0); symH := Lnewobj; move3Dobj(symH,0,0,v1.z); set3DRot(symH,rot.x,rot.y,rot.z,v1.x,v1.y,v1.z-baseElev); end else begin {3D symbol or plugin} btest := GetEntityMatrix(srcobjH,v1.x,v1.y,v1.z,rot.x,rot.y,rot.z); symbol('3D axes',v1.x,v1.y,0); symH := Lnewobj; move3Dobj(symH,0,0,v1.z); set3DRot(symH,rot.x,rot.y,rot.z,v1.x,v1.y,v1.z-baseElev); end; end; message(planarset,' ',v1,' ',rot,' elev ',baseElev); end; run(test); convertsymleveltest v2b.vwx Quote Link to comment
MullinRJ Posted February 23, 2023 Share Posted February 23, 2023 @BillW, I see what you mean by your code not working when a design layer has a z-offset. I have written a utility plug-in, Reshaper, that gets and sets object parameters. My Reshaper code and your code and the OIP agree when objects are placed on layers without a z-offset. Reshaper and your code also equally disagree withe the OIP when there is a layer offset, so you're basically doing things correctly. There may be a bug that needs to be exposed, but a workaround would be more useful. I have not tested my Reshaper code under these conditions, but I'm about to start. I'll keep you posted as I learn what's really going on, assuming I do. Raymond 2 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.