perspective projection 2D onto 3D

Next
 From:  pressure (PEER)
10807.1 
Hello,

I'm looking for suggestions on how to quickly make a perspective projection of points from 2D onto a 3D object. For example, say I want to make some marks on a 3D object so that the marks look like the letter "F" from a particular station point:



The method I've tried so far is to:
1. run ViewManager
2. place points at the Camera and Target locations saved by ViewManager
3. draw a plane normal to the principal ray defined by Camera and Target
4. project some vertices from 3D to 2D by manual ray tracing:



5. export an Ai, place a fiducial on this Ai, import the Ai back into MoI, and match the fiducial to a corner of my image plane using Transform > Orient (I could skip this step if importing curves placed those curves on x-y of the active cplane rather than x-y of world)
6. mirror and Transform > Scale the imported Ai so that vertices match up with the vertices that I projected by ray tracing:



7. Draw the letter "F" in the image plane
8. trace rays from vertices of 2D "F" onto 3D object:



9. connect the dots

All of this took a couple hours, making it impractical. I also noticed some inaccuracies from ray tracing. I'd like to do the 2D work in the same orientation as what the camera sees, rather than upside down and backwards, but this would require another projection which would double the work and probably the inaccuracy.

I did try simply overlaying a transparent reference image on the MoI viewport using another program and then tracing the reference image onto the 3D object using "On surface" object snapping, but since 3D zooming in MoI is done by moving the camera it's not possible to pan/zoom which makes tracing inaccurate. Also, this method doesn't let me take advantage of the sweet interactive tools in MoI for the 2D work.

I'm open to other software if someone knows of a NURBS package for doing this. While it would be cool to project curves, I only need to project points.

- Peer

EDITED: 3 Mar 2024 by PEER


  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
10807.2 In reply to 10807.1 
Hi Peer, so for making a curve in the view plane, you can set up a script on a keyboard shortcut to set the construction plane to the view plane as described here:
http://moi3d.com/forum/index.php?webtag=MOI&msg=2599.8

Then for doing the ray projections, try the attached script. There are instructions on how to install a plug-in command here.

Select point objects before running the ViewRaysThroughPoints command and it will generate rays going from the 3D view's camera point through the selected points.

Once the rays are generated you can then select them and your target object together and run Construct > Curve > Isect to generate points where the rays intersect the object.

- Michael

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  pressure (PEER)
10807.3 In reply to 10807.2 
Michael,

Wow! That is so cool that you wrote a script to do this, and in so few lines too!

I am very excited to use your new script and your old cplane to viewplane script tomorrow. I already tried both out and they look quite promising.

- Peer
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  pressure (PEER)
10807.4 In reply to 10807.2 
Hello,

The ray tracing script above didn't quite do what I want, so I spent the day trying to modify it. Now it does what I want about 2/3 of the time:



but sometimes it hangs (Calculating...) after doing a couple points.



If I terminate the script by hitting Save then I see that all rays were committed, but only the first 2 intersections were found:



I'm running this in v5beta on macOS. Please help me find my bug.

To test:
open attached 3dm file
run ViewManager script and select view1
select "test pts" from Objects
select top face of object
run script

code:
//v2 August 9, 2022

//convert a vector into a unit vector (length = 1)
function LengthSq( v )
{
	return ( v.x * v.x ) + ( v.y * v.y ) + ( v.z * v.z );
}

function Normalize( v )
{
	var lensq = LengthSq( v );
	if ( lensq > 1.0e-12 )
		v.scale( 1.0 / Math.sqrt( lensq ) );
}

//appends elements of 2nd object list to first
function CombineLists( targetlist, fromlist )
{
for ( var i = 0; i < fromlist.length; ++i )
targetlist.addObject( fromlist.item(i) );
}

//draw rays from selected point(s), through camera point, and beyond
function DoViewRaysThroughPoints()
{
	var pts = moi.geometryDatabase.getSelectedObjects().getPoints();

	if ( pts.length == 0 )
	{
		moi.ui.alert( 'error - no point objects selected' );
		return;
	}
	
	
	var faces = moi.geometryDatabase.getSelectedObjects().getFaces(); //ObjectList
	
		if ( faces.length == 0 )
	{
		moi.ui.alert( 'error - no face objects selected' );
		return;
	}

	var camerapt = moi.ui.mainWindow.viewpanel.getViewport('3D').cameraPt;

	for ( var i = 0; i < pts.length; ++i )
	{
		var ptobj = pts.item( i );

		var dir = moi.vectorMath.makeVector( camerapt, ptobj.pt );
		Normalize( dir );

		var line_length = 150.0;
		var startpt = ptobj.pt; //ray starts at selected point
		//ray goes through camera point and line_length beyond
		var endpt = moi.vectorMath.createPoint( camerapt.x - dir.x * line_length, camerapt.y - dir.y * line_length, camerapt.z - dir.z * line_length );
		var factory = moi.command.createFactory( 'line' ); //create ray
		factory.setInput( 0, startpt );
		factory.setInput( 1, endpt );
		
		var ray = factory.calculate(); 	
		factory.commit(); //plot intersections only and not rays by commenting out this line
		
		CombineLists(ray,faces) //append face Objects to ray ObjectList so that ray can be intersected with faces
		var iFactory = moi.command.createFactory('intersect');
		iFactory.setInput(0, ray);
		iFactory.commit();	
		
	}

}

DoViewRaysThroughPoints();

EDITED: 3 Mar 2024 by PEER


  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
10807.5 In reply to 10807.4 
Hi Peer, I'm trying to go through your steps but after I load the .3dm file and restore the saved view, I get this result:



The problem here is that the points are not positioned to be visible inside the view, they seem to be located somewhere behind the 3D view's camera point.

- Michael
Attachments:

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  pressure (PEER)
10807.6 In reply to 10807.5 
Michael,

The points should be located behind the camera point. They're on the "film plane" of the camera and will be projected out onto the 3D object. Like converting the camera into a slide projector. See screenshots above where rays all go through a point. That's the camera point.

- Peer
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
Next
 From:  Michael Gibson
10807.7 In reply to 10807.6 
Hi Peer, ok I see now - I had previously thought the rays would start at the camera point and go forward. You may need them to be a little longer if they're starting behind the camera point. Also the factory system may not be expecting to have a factory call both calculate() and also be used with update()/commit() as well with the same factory.

Does the attached version work any better for you?

- Michael

  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged

Previous
 From:  pressure (PEER)
10807.8 In reply to 10807.7 
Michael,

Thanks for teaching me that calculate() and commit() shouldn't be used on the same factory and for showing how to add the factory output to the geometryDatabase in another way.

- Peer
  Reply Reply More Options
Post Options
Reply as PM Reply as PM
Print Print
Mark as unread Mark as unread
Relationship Relationship
IP Logged
 

Reply to All Reply to All