From script to plugin - Speed

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
  02 February 2013
From script to plugin - Speed

I know its a really wide open question with lots of variables...no pun intended....and dependent on what is being done, but generally what are the speed increases when creating a plugin from a script?
 
  02 February 2013
totally unscientific I would say function calls are very slow (comparatively to c++) in mxs, both to other mxs functions and calls to compiled mxs exposed dlx functions.

saying that I don't think speed is always the reason to go down the plugin route, there are other considerations to take into account. Even though supporting a multitude of different versions and autodesk moving the goalposts every year A plugin is easier to manage as the complexity increases. It's usually a single entity (not always the case but mostly) which goes into one folder, you can even store multiple object/mods/utilities into a single plugin. Also it's a much nicer debugging environment in visual studio which also helps when complexity increases.

Another consideration is ui programming is much less work in mxs than in the sdk and much quicker to get something up and running and usuable.

Last edited by Klunk : 02 February 2013 at 02:34 PM.
 
  02 February 2013
As you already know, from 0% to 100000%. You at least need to clue us in on what the script does.
 
  02 February 2013
Generally it would involve raycasting i guess. Basically, taking a camera viewport and shooting rays out into the scene, through each pixel, and returning a cooresponding 3d coordinate. The script that i am using right now is slow, and we need to be able to use viewport/image sizes up to high end DSLR dimensions. I can post the code that i'm using... since its a sample that i found.
 
  02 February 2013
Here is the script (original author...Chris Shuman aka HybridArtist at maxforums) that i'm using..with a couple things added/removed.


 start = timeStamp()
 vp = viewport.activeViewport
 if viewport.IsPerspView() then
 (
 
 HitLocations = #() -- create array to hold hit locations
 viewportSize = getViewSize() -- get the currently selected viewport size
 print viewportSize  --prints out the captured viewport dimensions
 widthDiv = (1.0 / viewportsize[1]) * 2.0;
 	
 heightDiv = (1.0 / viewportsize[2]) * 2.0;
 	
 w2sMat = viewport.getTM();
 s2wMat = Inverse(w2sMat);--calc the screen-2-world matrix
 viewDir = -s2wMat.row3;
 viewOrigin = s2wMat.row4;
 s2wMat.row4 = [0,0,0];--remove any translation
 --print (ray viewOrigin viewDir);
 centerPos = viewOrigin * viewport.getTM();--project the viewpoint origin on screen
 rayDir = [0,0,0];
 
 for y = 1 to viewportsize[2] do -- foreach image row
 (
 for x = 1 to viewportsize[1] do -- foreach image column
 (
 for g in geometry do --foreach geometry object
 (
 local normX = (x * widthDiv) - 1.0;
 local normY = -((y * heightDiv) - 1.0);--invert the ycoord since y=0 represents upper edge
 local normPos = [normX,normY,-1.0];
 
 rayDir = normalize (normPos * s2wMat);
 tempRay = ray viewOrigin rayDir;
 
 IntRay = intersectray g tempRay;
 if intRay != undefined then
 (
 --print g;
 append HitLocations IntRay.pos; -- if hit add 3d position to "HitLocations Array"
 )
 )
 )
 )
 print HitLocations -- print hit locations to lisiner
 )
 else
 print "ERROR: no perspective viewport"
 end = timeStamp()
 format "Processing took % seconds\n" ((end - start) / 1000.0)
 


Be mindful that it will take a long time to process unless the current viewport is really small.
As i mentioned...the result needs to be way, way faster. Not sure if optimizing the script will do it or whether or not it needs to be a plugin.
 
  02 February 2013
if you merge the clones of scene geometry into a single mesh you can do something like this....

 start = timeStamp()
   vp = viewport.activeViewport
   if viewport.IsPerspView() then
   (
   
  	 HitLocations = #() -- create array to hold hit locations
  	 viewportSize = getViewSize() -- get the currently selected viewport size
  	 print viewportSize  --prints out the captured viewport dimensions
  	 widthDiv = (2.0 / (viewportsize[1] - 1));
  	 heightDiv = (2.0 / (viewportsize[2] - 1));
  	 w2sMat = viewport.getTM();
  	 s2wMat = Inverse(w2sMat);--calc the screen-2-world matrix
  	 viewDir = -s2wMat.row3;
  	 viewOrigin = s2wMat.row4;
  	 s2wMat.row4 = [0,0,0];--remove any translation
  	 centerPos = viewOrigin * viewport.getTM();--project the viewpoint origin on screen
  	 rayDir = [0,0,0];
  	 
  	 aspect = viewportSize.x/viewportSize.y;
  	 
  	 cGrid = RayMeshGridIntersect();
  	 cGrid.initialize 25;
  	 cGrid.addNode	$scene_geometry
  	 cGrid.buildGrid();
  	 
  	 for y = -1 to viewportsize[2] do -- foreach image row
  	 (
  		 for x = -1 to viewportsize[1] do -- foreach image column
  		 (
  			local normX = (x * widthDiv) - 1.0;
  			local normY = -((y * heightDiv) - 1.0);--invert the ycoord since y=0 represents upper edge
  			local normPos = [normX,normY/aspect,-aspect * 2];
  			raydir = normalize (normPos * s2wMat);
  			 
  			index = cGrid.intersectRay viewOrigin raydir false;
  			if index > 0 then
  			( 
  				chit = cGrid.getClosestHit()
  				pos =  viewOrigin + (rayDir * (cGrid.getHitDist chit))
  				append HitLocations pos; -- if hit add 3d position to "HitLocations Array"
  			)
  		 )
  	 )
  	 cGrid.free();
  	 
  	 fstream = openFile "c:\hitlocations.dat" mode:"wt";
  	 if fstream != undefined then
  	 (
  		for i in HitLocations do
  		(
  			format "%\n" i to:fstream;
  		)
  		flush	fstream;
  		close fstream;
  	)	
   )
   else
   print "ERROR: no perspective viewport"
   end = timeStamp()
   format "Processing took % seconds\n" ((end - start) / 1000.0)


also i fine tuned your method so you get a better resolution. takes about 30 secs on a 613 x 395 viewport and about 25% of that is saving the file.

Last edited by Klunk : 02 February 2013 at 09:59 AM.
 
  02 February 2013
How about doing a temp render and reading the resulting bitmap back in?
__________________
Hofer+Krol
 
  02 February 2013
hkrol

We originally tried it that way. Basically rendering a colour image and a cooresponding depth map. Our initial thought was that we could take the pixel colour from the render and the grayscale value from the depth map...which we could associate the min/max distance. This kind of worked as you can see from my example above...but it wasn't accurate.....or fast. The speed of acquiring the 3d points is the big issue. We would have anywhere between 200-1000 images to capture and recolour the 3d coordinate data from...even if its automated...the calculation times might become an issue.
 
  02 February 2013
I think a GLSL shader should be able to do this quite quickly. If you look at the last example on the page below, the shader is returning a value based on the normal direction of the surface. It shouldn't be too difficult to get it to return a colour based on position of the surface at that point.
http://www.spot3d.com/vray/help/200...es_vrayglsl.htm
 
  02 February 2013
I'm not really the best coder here, but I got your script down from 594 seconds to 16 seconds with 2 objects that fill the screen at 613x395.

Basically I tried to use less variables in the loop. And print to memory instead of the listener.

At first I didn't realize you were trying to save the hit locations, and it only takes about 6 seconds for the actual intersectRay fucntion. So the rest is saving the file. There must be a faster way to do that.


(
	start = timeStamp()
	s = "" as stringStream
	vp = viewport.activeViewport

	if viewport.IsPerspView() then
	 (
		 viewportSize = getViewSize() -- get the currently selected viewport size
		 widthDiv = (1.0 / viewportsize[1]) * 2.0;
		 heightDiv = (1.0 / viewportsize[2]) * 2.0;
			
		 w2sMat = viewport.getTM();
		 s2wMat = Inverse(w2sMat);--calc the screen-2-world matrix
		 viewDir = -s2wMat.row3;
		 viewOrigin = s2wMat.row4;
		 s2wMat.row4 = [0,0,0];--remove any translation
		 
		 for y = 1 to viewportsize[2] do -- foreach image row
		 (
			 for x = 1 to viewportsize[1] do -- foreach image column
			 (
				 rayDir = (ray viewOrigin (normalize (([(x * widthDiv) - 1.0,-((y * heightDiv) - 1.0),-1.0]) * s2wMat)))
				 
				 for g in geometry do --foreach geometry object
				 (
					 IntRay = intersectray g rayDir;
					 if intRay != undefined then
					 (
						 format "%\n" IntRay.pos to:s
					 )
				 )
			 )
		 )

		fName = "$temp\SaveHitLocations.txt"
		cf = createFile fName
		format "%" (s as string) to:cf
		close cf
		edit fName
	 )
	 else
	 (
		print "ERROR: no perspective viewport"
	 )
	 
	end = timeStamp()
	format "Processing took % seconds\n" ((end - start) / 1000.0)
)
__________________
Juan Martinez | Blog | Animator

Last edited by martinez : 02 February 2013 at 11:04 PM.
 
  02 February 2013
It very much depends on what you're doing with the data later. What would a printout to the listener help you anyways?
 
  02 February 2013
The output was going to go into its own file ultimately...i thought it was the same...speed wise...to print to the listener. At least for now.

I just wanted to clarify the process that we are thinking about here...because we might be going down the wrong path all together to get what we need. We, ideally, want to re-colour pointcloud data with photographs that we take from a mobile scanning rig we are designing....or at least thinking of designing. So basically we would have cameras doing image capture and these images would then have a corresponding camera in 3d. The rays would be sent out through this camera matched view, the pixel colours from the photo would give us the point colour while the raycast would give us the 3d coordinate. So then we could write out the new pointcloud in the form:

2 2 2 255 255 255
3 3 3 200 200 200

It may seem like a long way to go to colour some points but the data acquisition of the point cloud is almost always limited to night time scanning so that's one of the reasons for breaking up the photos and the scanning....or else we would just do full colour scans. I really appreciate all the help...like most things it looks like its getting more complex before it gets simpler!
 
  02 February 2013
I'm not sure I fully understood the process, but regarding writing to file, you will get much better performance (and smaller files) writing binary data instead of ascii text.
 
  02 February 2013
Thread automatically closed

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
__________________
CGTalk Policy/Legalities
Note that as CGTalk Members, you agree to the terms and conditions of using this website.
 
Thread Closed share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 05:55 PM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.