Jump to content
Developer Wiki and Function Reference Links ×

Get 3D location of symbols or plugin objects


BillW

Recommended Posts

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

 

check piosym 3D location.png

sympio baselev test.vwx

Link to comment

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.

  • Like 1
Link to comment

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.

Link to comment

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);

 

check piosym 3D location v2.png

convertsymleveltest v2.vwx

Link to comment

@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

 

 

Link to comment

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);

 

check piosym 3D location v2b.png

convertsymleveltest v2b.vwx

Link to comment

@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

  • Like 2
Link to comment

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...