Split Polygon on Intersection


#1

Hello,

I am working with my friends realtime renderer he’s written. Its pretty simple and doesnt account for transparent objects very well.
For example creating trees and foliage for realtime requires many intersecting polys with trransparency. Most renderers handle the draw order of the transparent objects pretty good but the renderer I am using does not. It gets confused when transparent objects intersect and draws only one at a time depending on the plane of view.

A quick hack maybe is to split the polys where they intersect using a script. Does anyone know how to accomplish such a feat?
What I am trying to do is split a polygon along the lines of an intersecting polygon.

Thanks for any clues


#2

Hmm I found something that sounds like it would do the trick…except it appears the link is broken for something called:

quickcollapse union ms

by Dave Buchofer.

Anyone know where one could get this again?


#3

fn intersectCut node:selection[1] = if iskindof node GeometryClass do 
(
convertToMesh node
node.selectedverts = #{}
slice = copy node
node -= slice
delete slice
convertToPoly node
polyop.breakVerts node (node.selectedverts as bitarray)
select node
node
)

something like that… Try this. If it will not work for you, I have another one :wink:


#4

Thanks very much for the reply!

I will try this out as soon as i am able to and let you know what I find…thanks again. Sorry I did not reply sooner.

Thank you


#5

Hi denisT,

I tried the script but no luck.
With 2 intersecting planes…nothing appears to be happening to the polygons.
When I tried it with 2 intersecting boxes…one of the boxes dissappears.

In both cases there is no change to the polygon structure???

You mentioned another idea you had? I appreciate the help!


#6

when you talk about “poly” do you mean “polygon” or “edit_poly” node?


#7

I am sorry if it didnt explain my situation correctly.

If I have 2 plane objects (plane object 1 and plane object2) that are quad polygons in structure that intesect each other—the polygons from obj1 and obj2 needs to be cut along where the other polygons intersect.

If they were positioned in an “X” shape the plane objects would each become a 2 polygon object cut diagonally.


#8

ok … here is another solution:


fn flatFacesPlane faces: node:selection[1] =
(
 if faces == unsupplied do faces = node.faces as bitarray
  
 if not faces.isempty then
 (
  local pos = [0,0,0]
  local dir = [0,0,0]
  for f in faces do
  (
   pos += polyop.getfacecenter node f
   dir += polyop.getfacenormal node f
  )
  ray (pos/faces.numberset) (normalize (dir/faces.numberset))
 )
 else (ray [0,0,0] [0,0,1])
)
fn planeCut plane1:selection[1] plane2:selection[2] = if iskindof plane1 GeometryClass and iskindof plane2 GeometryClass do 
(
 
 if not iskindof plane1 Editable_Poly do convertToPoly plane1
 if not iskindof plane2 Editable_Poly do convertToPoly plane2
 
 slice1 = flatFacesPlane node:plane1
 slice2 = flatFacesPlane node:plane2
  
 polyop.slice plane1 plane1.faces slice2
 polyop.splitEdges plane1 plane1.selectededges
 polyop.slice plane2 plane2.faces slice1
 polyop.splitEdges plane2 plane2.selectededges
)

  1. select both planes
  2. run “planeCut()”

I don’t double check real intersection of this two planes but if you need I can add it to the code…


#9

 
fn planeCut plane1:selection[1] plane2:selection[2] = if iskindof plane1 GeometryClass and iskindof plane2 GeometryClass and (intersects plane1 plane2) do 
(
fn flatFacesPlane faces: node:selection[1] =
(
if faces == unsupplied do faces = node.faces as bitarray
 
if not faces.isempty then
(
local pos = [0,0,0]
local dir = [0,0,0]
for f in faces do
(
	pos += polyop.getfacecenter node f
	dir += polyop.getfacenormal node f
)
ray (pos/faces.numberset) (normalize (dir/faces.numberset))
)
else (ray [0,0,0] [0,0,1])
)
 
if not iskindof plane1 Editable_Poly do convertToPoly plane1
if not iskindof plane2 Editable_Poly do convertToPoly plane2
 
slice1 = flatFacesPlane node:plane1
slice2 = flatFacesPlane node:plane2
 
polyop.slice plane1 plane1.faces slice2
polyop.splitEdges plane1 plane1.selectededges
update plane1
polyop.slice plane2 plane2.faces slice1
polyop.splitEdges plane2 plane2.selectededges
update plane2
ok
)

  1. select both planes
  2. run “planeCut()”

I added double check for bbox intersection of this two planes…


#10

Wow! works very beautifully!

Does this account for say if there are multiple intersections occuring accross the planes (i tried it with three intersecting planes but it only took the first 2–seemingly.
I am very impressed though.

[EDIT] Oh I see, upon further inspection of the code it looks like it is hardcoded for 2 intersecting planes? Is it difficult to extend this to bunches of intersecting planes? Like realtime trees…


#11

fn multyPlaneCut planes:(selection as array) =
(
 
fn flatFacesPlane faces: node:selection[1] =
(
if faces == unsupplied do faces = node.faces as bitarray
 
if not faces.isempty then
(
local pos = [0,0,0]
local dir = [0,0,0]
for f in faces do
(
	pos += polyop.getfacecenter node f
	dir += polyop.getfacenormal node f
)
ray (pos/faces.numberset) (normalize (dir/faces.numberset))
)
else (ray [0,0,0] [0,0,1])
)
local slice_planes = #()
for p in planes where iskindof p GeometryClass do
(
if not iskindof p Editable_Poly do convertToPoly p
slicers = for s in planes where p != s and iskindof s GeometryClass and (intersects p s) collect
(
if not iskindof s Editable_Poly do convertToPoly s
slicer = flatFacesPlane node:s
)
append slice_planes #(p, slicers)
)
 
for p in slice_planes do
(
for s in p[2] do
(
polyop.slice p[1] p[1].faces s
polyop.splitEdges p[1] p[1].selectededges
)
update p[1]
)
ok
)

here is a multi-plane version…

  1. select all planes
  2. run “multyPlaneCut()”

PS. It’s not optimized! But it easy to do… :wink:


#12

This is so great…I am very impressed by your work and I cant thank you enough. This is exactly what we are looking for.
I can see alot of potential too—(such as cut a plane along a curved intersections etc.)—and I think with your code as a start I can see if I can contribute anything and post it here too.
Thanks again for the brilliant work.


#13

Wecome! Good luck.


#14

Hello again denisT,

Ive been using your script it is great, Ive been giving you tons a credit too.
I had onerequest/idea…would it be hard to implement this into the code:

After a plane is split (by n-number of intersections), each resulting split polygon will detach into a new object by itself.( e.g. plane with 2 horizontal intersections—will be plane, plane01, plane02)

This sounds like it would generate a TON of new objects and normally it would but the renderer is having problems with the draw order still…so…I am thinking with a controlled number of intersections this might force the renderer to sort the draw orders properly.
Thanks for any help!


#15

a renderer will have the worse problem with a TON objects I guess. But here is a function how to split poly node by elements


fn separateByFaceElements obj:selection[1] = if iskindof obj Editable_Poly do
(
local elements = #()
local faces = obj.faces as bitarray
while (f = (faces as array)[1]) != undefined do 
(
ff = polyop.getElementsUsingFace obj #{f}
append elements ff
faces -= ff
)
local nodes = #()
for k=2 to elements.count collect
(
if (polyOp.detachFaces obj elements[k] delete:on asNode:on name:(uniqueName obj.name)) do append nodes objects[objects.count]
)
update obj
join #(obj) nodes
)
 

it returns list of nodes (original one + newly created). After that you have to do somethihg with there thransforms, because they all inherit transform from original node.


#16

Thanks very much…Ill let you know what happens!

Again, I appreciate the help.


#17

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.