Писался на коленке, имеет очень большой потенциал для оптимизации и, соответственно, ускорения.
----------------------------------------------------------------------------------------------max2014
rollout ObjInt "Objects Intersection" width:400
(
button create01 "Create" width:100 align:#center
group "Parameters Objects"
(
label lblt1 "--------- Object 1 -------------------" align:#center
spinner obj1x "X:" width:100 range:[-1000.0,1000.0, 8.0] type:#float align:#right across:4
spinner obj1y "Y:" width:100 range:[-1000.0,1000.0, 0.0] type:#float align:#right
spinner obj1z "Z:" width:100 range:[-1000.0,1000.0,4.0] type:#float align:#right
spinner obj1rad "Rad:" width:100 range:[-1000.0,1000.0,20.0] type:#float align:#right
label lblt2 "----------- Object 2 ------------------" align:#center
spinner obj2x "X:" width:100 range:[-1000.0,1000.0, 30.0] type:#float align:#right across:4
spinner obj2y "Y:" width:100 range:[-1000.0,1000.0, 0.0] type:#float align:#right
spinner obj2z "Z:" width:100 range:[-1000.0,1000.0,0.0] type:#float align:#right
spinner obj2rad "Rad:" width:100 range:[-1000.0,1000.0,10.0] type:#float align:#right
)
--**********************
fn CreateSP PointA PointB theCol =
(
local SP = SplineShape name: (uniquename "spline")
addNewSpline SP
addKnot SP 1 #corner #line PointA
addKnot SP 1 #corner #line PointB
SP.wirecolor = theCol
SP.render_displayRenderMesh = true
SP.render_viewport_thickness = 0.2
updateShape SP
)
--**********************
fn createObjects =
(
try(delete objects)catch()
local obj1 = GeoSphere pos: [obj1x.value, obj1y.value, obj1z.value] radius: obj1rad.value name:(uniquename "sphere") segs:2,
obj2 = GeoSphere pos: [obj2x.value, obj2y.value, obj2z.value] radius: obj2rad.value name:(uniquename "sphere") segs:2
)
--************************
fn PointInFace P1 P2 P3 P =
(
local vec1 = P2 - P1
local vec2 = P3 - P1
local squareFace = (length(cross vec1 vec2))/2.0
-----
local vec3 = P1 - P
local vec4 = P2 - P
local squareFace1 = (length(cross vec3 vec4))/2.0
-----
local vec5 = P2 - P
local vec6 = P3 - P
local squareFace2 = (length(cross vec5 vec6))/2.0
----
local vec7 = P3 - P
local vec8 = P1 - P
local squareFace3 = (length(cross vec7 vec8))/2.0
local sumArea = squareFace1 + squareFace2 + squareFace3
if sumArea <= 1.000001*squareFace then return(true) else return(false)
)
--************************
fn findInterLinePlane planeP1 planeP2 planeP3 lineP1 lineP2 =
(
local n = cross (planeP2-planeP1) (planeP3-planeP1)
local normalPlane = n/(length n)
local V = planeP1 - lineP1,
D = dot normalPlane V,
W = lineP2 - lineP1,
theE = dot normalPlane W
local thePos = if theE != 0 then lineP1 + W*D/theE else (lineP1 + lineP2)/2.0
local LengthPos = length (lineP1 - thePos) + length (lineP2 - thePos)
local lengthLine = 1.000001*length(lineP1 - lineP2)
if (LengthPos <= lengthLine) and (PointInFace planeP1 planeP2 planeP3 thePos == true) then return(thePos) else return(undefined)
)
--************************
--************************
fn findInterFaces planeP1 planeP2 planeP3 lineP1 lineP2 =
(
local n = cross (planeP2-planeP1) (planeP3-planeP1)
local normalPlane = n/(length n)
local V = planeP1 - lineP1,
D = dot normalPlane V,
W = lineP2 - lineP1,
theE = dot normalPlane W
local thePos = if theE != 0 then
(
lineP1 + W*D/theE
) else (lineP1 + lineP2)/2.0
local LengthPos = length (lineP1 - thePos) + length (lineP2 - thePos)
local lengthLine = 1.000001*length(lineP1 - lineP2)
if (LengthPos <= lengthLine) and (PointInFace planeP1 planeP2 planeP3 thePos == true) then return(thePos) else return(undefined)
)
--************************
fn findTriagInter faceA faceB =
(
local A = faceA[1],
B = faceA[2],
C = faceA[3],
M1 = faceB[1],
M2 = faceB[2],
M3 = faceB[3]
local theArr = #()
if findInterLinePlane A B C M1 M2 != undefined do append theArr (findInterLinePlane A B C M1 M2)
if findInterLinePlane A B C M1 M3 != undefined do append theArr (findInterLinePlane A B C M1 M3)
if findInterLinePlane A B C M2 M3 != undefined do append theArr (findInterLinePlane A B C M2 M3)
----
if findInterLinePlane M1 M2 M3 A B != undefined do append theArr (findInterLinePlane M1 M2 M3 A B)
if findInterLinePlane M1 M2 M3 A C != undefined do append theArr (findInterLinePlane M1 M2 M3 A C)
if findInterLinePlane M1 M2 M3 B C != undefined do append theArr (findInterLinePlane M1 M2 M3 B C)
if theArr.count == 2 do CreateSP theArr[1] theArr[2] red
)
--************************
fn getObjInter object1 object2 =
(
progressstart "Iteration ..."
convertToMesh object1
convertToMesh object2
local n = 0
local numf = object1.numfaces
for i in object1.faces do
(
local face1 = #()
local index1 = (meshop.getVertsUsingFace object1 i.index) as array
append face1 (getVert object1 index1[1])
append face1 (getVert object1 index1[2])
append face1 (getVert object1 index1[3])
for j in object2.faces do
(
local face2 = #()
local index2 = (meshop.getVertsUsingFace object2 j.index) as array
append face2 (getVert object2 index2[1])
append face2 (getVert object2 index2[2])
append face2 (getVert object2 index2[3])
findTriagInter face1 face2
)
progressupdate (100.0*n/numf)
n+=1
)
progressend ()
)
--************************
fn theAllFunc =
(
createObjects()
getObjInter $sphere001 $sphere002
)
--************************
on create01 pressed do theAllFunc()
--------------------------------
on obj1x changed val do theAllFunc()
on obj1y changed val do theAllFunc()
on obj1z changed val do theAllFunc()
on obj1rad changed val do theAllFunc()
on obj2x changed val do theAllFunc()
on obj2y changed val do theAllFunc()
on obj2z changed val do theAllFunc()
on obj2rad changed val do theAllFunc()
)--end rollout
createDialog ObjInt escapeEnable: true
--------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------max2014
rollout ObjInt "Objects Intersection" width:400
(
button create01 "Create" width:100 align:#center
group "Parameters Objects"
(
label lblt1 "--------- Object 1 -------------------" align:#center
spinner obj1x "X:" width:100 range:[-1000.0,1000.0, 8.0] type:#float align:#right across:4
spinner obj1y "Y:" width:100 range:[-1000.0,1000.0, 0.0] type:#float align:#right
spinner obj1z "Z:" width:100 range:[-1000.0,1000.0,4.0] type:#float align:#right
spinner obj1rad "Rad:" width:100 range:[-1000.0,1000.0,20.0] type:#float align:#right
label lblt2 "----------- Object 2 ------------------" align:#center
spinner obj2x "X:" width:100 range:[-1000.0,1000.0, 30.0] type:#float align:#right across:4
spinner obj2y "Y:" width:100 range:[-1000.0,1000.0, 0.0] type:#float align:#right
spinner obj2z "Z:" width:100 range:[-1000.0,1000.0,0.0] type:#float align:#right
spinner obj2rad "Rad:" width:100 range:[-1000.0,1000.0,10.0] type:#float align:#right
)
--**********************
fn CreateSP PointA PointB theCol =
(
local SP = SplineShape name: (uniquename "spline")
addNewSpline SP
addKnot SP 1 #corner #line PointA
addKnot SP 1 #corner #line PointB
SP.wirecolor = theCol
SP.render_displayRenderMesh = true
SP.render_viewport_thickness = 0.2
updateShape SP
)
--**********************
fn createObjects =
(
try(delete objects)catch()
local obj1 = GeoSphere pos: [obj1x.value, obj1y.value, obj1z.value] radius: obj1rad.value name:(uniquename "sphere") segs:2,
obj2 = GeoSphere pos: [obj2x.value, obj2y.value, obj2z.value] radius: obj2rad.value name:(uniquename "sphere") segs:2
)
--************************
fn PointInFace P1 P2 P3 P =
(
local vec1 = P2 - P1
local vec2 = P3 - P1
local squareFace = (length(cross vec1 vec2))/2.0
-----
local vec3 = P1 - P
local vec4 = P2 - P
local squareFace1 = (length(cross vec3 vec4))/2.0
-----
local vec5 = P2 - P
local vec6 = P3 - P
local squareFace2 = (length(cross vec5 vec6))/2.0
----
local vec7 = P3 - P
local vec8 = P1 - P
local squareFace3 = (length(cross vec7 vec8))/2.0
local sumArea = squareFace1 + squareFace2 + squareFace3
if sumArea <= 1.000001*squareFace then return(true) else return(false)
)
--************************
fn findInterLinePlane planeP1 planeP2 planeP3 lineP1 lineP2 =
(
local n = cross (planeP2-planeP1) (planeP3-planeP1)
local normalPlane = n/(length n)
local V = planeP1 - lineP1,
D = dot normalPlane V,
W = lineP2 - lineP1,
theE = dot normalPlane W
local thePos = if theE != 0 then lineP1 + W*D/theE else (lineP1 + lineP2)/2.0
local LengthPos = length (lineP1 - thePos) + length (lineP2 - thePos)
local lengthLine = 1.000001*length(lineP1 - lineP2)
if (LengthPos <= lengthLine) and (PointInFace planeP1 planeP2 planeP3 thePos == true) then return(thePos) else return(undefined)
)
--************************
--************************
fn findInterFaces planeP1 planeP2 planeP3 lineP1 lineP2 =
(
local n = cross (planeP2-planeP1) (planeP3-planeP1)
local normalPlane = n/(length n)
local V = planeP1 - lineP1,
D = dot normalPlane V,
W = lineP2 - lineP1,
theE = dot normalPlane W
local thePos = if theE != 0 then
(
lineP1 + W*D/theE
) else (lineP1 + lineP2)/2.0
local LengthPos = length (lineP1 - thePos) + length (lineP2 - thePos)
local lengthLine = 1.000001*length(lineP1 - lineP2)
if (LengthPos <= lengthLine) and (PointInFace planeP1 planeP2 planeP3 thePos == true) then return(thePos) else return(undefined)
)
--************************
fn findTriagInter faceA faceB =
(
local A = faceA[1],
B = faceA[2],
C = faceA[3],
M1 = faceB[1],
M2 = faceB[2],
M3 = faceB[3]
local theArr = #()
if findInterLinePlane A B C M1 M2 != undefined do append theArr (findInterLinePlane A B C M1 M2)
if findInterLinePlane A B C M1 M3 != undefined do append theArr (findInterLinePlane A B C M1 M3)
if findInterLinePlane A B C M2 M3 != undefined do append theArr (findInterLinePlane A B C M2 M3)
----
if findInterLinePlane M1 M2 M3 A B != undefined do append theArr (findInterLinePlane M1 M2 M3 A B)
if findInterLinePlane M1 M2 M3 A C != undefined do append theArr (findInterLinePlane M1 M2 M3 A C)
if findInterLinePlane M1 M2 M3 B C != undefined do append theArr (findInterLinePlane M1 M2 M3 B C)
if theArr.count == 2 do CreateSP theArr[1] theArr[2] red
)
--************************
fn getObjInter object1 object2 =
(
progressstart "Iteration ..."
convertToMesh object1
convertToMesh object2
local n = 0
local numf = object1.numfaces
for i in object1.faces do
(
local face1 = #()
local index1 = (meshop.getVertsUsingFace object1 i.index) as array
append face1 (getVert object1 index1[1])
append face1 (getVert object1 index1[2])
append face1 (getVert object1 index1[3])
for j in object2.faces do
(
local face2 = #()
local index2 = (meshop.getVertsUsingFace object2 j.index) as array
append face2 (getVert object2 index2[1])
append face2 (getVert object2 index2[2])
append face2 (getVert object2 index2[3])
findTriagInter face1 face2
)
progressupdate (100.0*n/numf)
n+=1
)
progressend ()
)
--************************
fn theAllFunc =
(
createObjects()
getObjInter $sphere001 $sphere002
)
--************************
on create01 pressed do theAllFunc()
--------------------------------
on obj1x changed val do theAllFunc()
on obj1y changed val do theAllFunc()
on obj1z changed val do theAllFunc()
on obj1rad changed val do theAllFunc()
on obj2x changed val do theAllFunc()
on obj2y changed val do theAllFunc()
on obj2z changed val do theAllFunc()
on obj2rad changed val do theAllFunc()
)--end rollout
createDialog ObjInt escapeEnable: true
--------------------------------------------------------------------------------------