Notifications
Clear all

[Closed] how to get objects faces in camera view ?

i want to write a script to delete all object faces which are not in camera view window . because the scene is too big and when the camera is animated by a path , only a little part of scene is in the camera view . and other no_useful objects faces can be deleted . it will make my render process faster ,
my idea :
1 .

use ray , intersectRayEx <obj> <ray> , make many rays from the camera , caculate the intersection ,get the obj and the face intersected ,then get the element with own the face …
after collect all #(obj , ( face of element index to delete ) ) , then delete all the elements .

1.result : everything ok , but the key question is : too many rays needed to cover all camera view ,and it will lost some thing to delete , and it runs very slow with intersectRayEx ()


if max has a function to check if the object is in camera view window ,like :

is_Been_See_By_Camera <object> <camera>

and if possable returns the face index number like intersectRay()


or i can set a light same as the camera , so turn off all lights but this one , when camera goes , the light goes too , the lights lighting area is the cameras view area. so if ok , the question is :

if mesh or poly has some property that related with the light who lighting him ? like :

been_lighted_faces <mesh or poly>
been_lighted_vertexes <mesh or poly>
… …
which can help me filter out the lighting faces .


im still thinking ideas , maybe there have some simple and smart idea exist .

wish some one can help me thinking about the No. 2 and No.3 idea . thanks .

9 Replies
 rdg

Hello Lan,

a simple and smart idea exists.
I read about it in the forum:

You need to create a cone object the size of your Camera FOV and depth.
Apply a Volume-Select Modifier to all objects you want to trim.
Put a Delete Mesh Modifier on top.

Pro: This deletes all geometry outside the camera cone.
Con: Works only with Editable Mesh (?) So maybe some Cache-Modifiers for animations is needed.

But with a little script here and a little script there this could be a fast way to trim your objects.

Georg

If your scene has many objects, I would advise writing a script that checks only the bbox against the camera cone and creates visibility keys per frame for single objects over the course of animation. I have done this and can confirm that it speeds up render times significantly. The only problem would be if you have raytraced reflections – objects might pop up in reflections…

  1. thanks rdg :

i will try use this idea , it looks smart ,i know alter the camera to a light , why not a selection cone ? thanks very much .

2.thanks bobo :

hide object is a good idea , if have many objects and the objects has not very much faces , i think it works very good , now my scene object has many faces , cause when after model they will collapse all objects , so i have to think about delete elements faces .

Ok, then take a look at the MAXScript Reference:
*How to ... Develop a Vertex Renderer - this shows some code how to calculate the screen coordinates of a vertex. Each face has 3 vertices. If all 3 vertices have their screen coordinates OUTSIDE of the projection plane (either a negative X or Y, or higher than the image size), then the face is not in the camera view. This is much much faster than IntersectRay.

NOTE: You could run a test for each vertex first and store the results for the current frame in a bitarray (true if in view, false if outside). Then loop through all faces, get the face, for each of its 3 vertices look into the bitarray to see all are false and if it is the case, collect the face index to be deleted later. This will avoid checking a vertex shared by multiple faces multiple times and speed up the process…

*FAQ &gt; How Do I Get Faces With Normals Facing Away? - this topic shows how to find out which faces are facing away from the camera. This is like a permanent Backface cull - you could run a test on each frame for each face and if the face is ALWAYS facing away, you could delete it permanently.

In all these cases, I suggest using MeshSelect modifier with DeleteMesh on top. This way, you can change the selection in the MeshSelect modifier or disable the modifiers to return to the original meshes (NON-DESTRUCTIVE!). All the faces will still save with the file, but will not be visible to the renderer and save render times. You could collapse the stack anytime to bake the changes, of course...

Didn’t Blur release a script to do exactly this. They used it to optimize the renders on their ride-films.

I don’t know the link off the top of my head, but it could save you some time if you could find it.

to bobo :

thanks , maybe the second idea is the fastest one . u have tell us dont access vertex if possible , and i think if a vertex is hide by other object at front of it , it is in camera view but i dont need it .
so i will try access faces .

to thatoneguy:

post my old codes using intersectRayEx () ,it is slow ,but u can know what i say .
the code is only for test , and maybe not run properly, i have edit it many times .

--this script is for delete all objects and object elements which cant see in the 
--camera when camera is animated or not . 
--cause , if a scene is too big , and a camera`s animation is short ,only cover part
-- of the objects , i want delete all no used faces to make my render faster . 
rollout delete_elements "delete obj&faces for render"
(
-------------------------------------------------------
button deleteElementsNow "del elements"
progressbar iRayBar color:black 
---------------------------------------------------------------------------
fn sel_objs =
(
local theR =#()
/*
if selection.count!=0 then ( theR=for i in selection where classof i==editable_mesh collect i )
else (theR=for i in geometry where classof i==editable_mesh collect i )
*/
theR=for i in geometry where classof i== editable_mesh collect i 
return theR 
)-- end sel objs .
---------------------------------------------------------------------------
fn mesh_rays theMatrix width_seg:2 length_seg:20 length_:100 width_:100 =
(
ssss=plane name:"lanhaibo_radial_helper" 
ssss.typeinCreationMethod=1 
--ssss.typeinlength=100
--ssss.typeinwidth=100 
ssss.length=length_
ssss.width=width_
ssss.length_segments=length_seg 
ssss.width_segments=width_seg 
-- for this angle is 90.0,by a sqare box , the using angle is 77.569. 28mm .
-- so this value can  be changed by count .
-- ssss.pos=((arctg( 77.569/2))*(100/2))
ssss.pos=[0,0,50] 
ssss.pivot=[0,0,0]
--should use matrix 3 .align the face to the camera.--
ssss.transform = theMatrix --thecamera.transform 
--note : 
 -- the matrix of the camera is a inverse direction !! 
--convert ss to mesh and get the vertex positions -- 
convertto ssss editable_mesh 
local theNumVerts= getNumverts ssss
local vertPosArray=for i=1 to theNumVerts collect (getvert ssss i)
local theZero=ssss.pos
local theRays=for i in vertPosArray collect (ray theZero (theZero-i))
-- note , this ray use (theZero - i) because the dir of the camera is inversed .
delete ssss
return theRays 
)
----------------------------------------------------
fn createRays theCamera theBar timeBegin:0 timeEnd:100  = 
(
-- the max angle 45 45 60 ,use a sqare as the camera`s view port , the maximum of FOV . 
-- lens:28mm fov:65.47 xfov:77.569 deg.
local theRaysCreated=#()
for i=timeBegin to timeEnd do 
 (
 at time i
  (
  local exp_rays=mesh_rays theCamera.transform
  theRaysCreated+=exp_rays
  )
 local tEnd=timeEnd as integer
 local tBegin=timeBegin as integer 
 theBar.value=((i as integer)-tBegin)/(tEnd-tBegin)*100
 
 )
 return theRaysCreated 
)
----------------------------------------------------
fn QsortCompare qa qb = 
(
--#( #(ray pos:pos dir:normal, 6, barycentric coordinates) ,j object, i ray)
local theDistance1 = distance qa[1][1].pos qa[3].pos
local theDistance2 = distance qb[1][1].pos qb[3].pos 
local theCom=theDistance1 - theDistance2 
return theCom 
)
-----------------------------------------------------
fn del_faces obj rays = 
with redraw off(
local faces_x=#{}
for i in rays do 
 (
 local  tempFaces = #{}
 local tempInterX = intersectRayEx obj i
   [email="--@@@@--#(ray"]--@@@@--#(ray[/email] pos:pos dir:normal, 6, barycentric coordinates )
   if tempInterX != undefined do 
  (
  tempFaces[(tempInterX[2])] = true 
  faces_x += tempFaces
  )--end if tempinterx
  
 )--end for i in rays 
---now get faces_x for intersect faces --- 
---caculate the elements faces using the faces_x --- 
if (not faces_x.isEmpty) do 
 (
 -- meshop.getElementsUsingFace <Mesh mesh> <facelist> fence:<facelist=unsupplied>
 local faces_x_exp=#{}
 faces_x_exp = meshop.getElementsUsingFace obj faces_x 
 -- so the delete faces is the inverse if faces_x_exp 
 local inv_faces_x_exp = -faces_x_exp
 --delete the unused faces 
 meshop.deletefaces obj inv_faces_x_exp
-- update obj
 )--end if faces_x.count
)-- end fn del_faces 
-------------------------------------------------------
on deleteElementsNow pressed do 
(
local theCameraUsing = getActiveCamera()
local theRays=#()
local theobjs_ray_elements =#()
local theTimebegin=animationRange.start
local theTimeend=animationRange.end
iRayBar.value=0
max create mode 
undo off
 (
 if theCameraUsing != undefined do 
  (
  -- init ---
  theRays=createRays theCameraUsing iRayBar timeBegin:theTimeBegin timeEnd:theTimeEnd 
  theobjs_ray_elements=sel_objs()
  --local thecount=theobjs_ray_elements.count
  -- loop with the ray . count only near face . 
  del_faces theobjs_ray_elements therays
	
  )-- end if thecamera != undefined . 
 )-- end undo off . 
)-- end button pressed 
-------------------------------------------------------
)-- end rollout delete elements .
createdialog delete_elements 

the most important thing in scripting is not writing script but the idea .about something u thinking .

1 Reply
(@bobo)
Joined: 12 months ago

Posts: 0

Hey, I have been saying that for 9 years
You are correct, my friend, that is the key!

wow that volume select modifier seems cool, Ill have to look into whats exposed via maxcript there