Advertisement
Guest User

Untitled

a guest
Aug 31st, 2015
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.68 KB | None | 0 0
  1. // Based on the SDK Sampl GeometryCreation_BooleanOperations
  2. // This is testing code. Many improvements can be made before use in real work
  3.  
  4. #r @"C:\Program Files\Autodesk\Revit 2016\RevitAPI.dll"
  5. #r @"C:\Program Files\Autodesk\Revit 2016\RevitDBAPI.dll"
  6. #r @"C:\Program Files\Autodesk\Revit 2016\RevitAPIUI.dll"
  7. #r @"C:\Program Files\Mantis\Tsunami.IDEDesktop.dll"
  8.  
  9. open Autodesk.Revit
  10. open Autodesk.Revit.UI
  11.  
  12. open System
  13. open System.Linq
  14. open System.Collections.Generic
  15.  
  16.  
  17. open Autodesk.Revit.DB
  18. open Autodesk.Revit.DB.Analysis
  19. open Autodesk.Revit.DB.Architecture
  20. open Autodesk.Revit.UI
  21. open Autodesk.Revit.UI.Selection
  22. open Autodesk.Revit.ApplicationServices
  23. open Autodesk.Revit.Attributes
  24.  
  25. open System.Collections.Generic
  26. open System.Collections.Concurrent
  27.  
  28. let memoize f =
  29. let cache = new ConcurrentDictionary<'a,'b>()
  30. fun x ->
  31. match cache.TryGetValue(x) with
  32. | (true,y) -> y
  33. | (false,_) ->
  34. let y = f x
  35. cache.[x] <- y
  36. y
  37.  
  38. module Option =
  39. /// nullable
  40. let ofNullable (x : 'a) = if box x <> null then Some x else None
  41. /// System.Nullable
  42. let ofSystemNullable (x : System.Nullable<'a>) = if x.HasValue then Some x.Value else None
  43.  
  44. let tryGetAll (xs:'a option []) =
  45. if xs |> Array.exists (function | None -> true | _ -> false)
  46. then None
  47. else xs |> Array.map (Option.get) |> Some
  48.  
  49.  
  50. let tryNull (x:'a) = if box x <> null then Some(x) else None
  51.  
  52.  
  53.  
  54.  
  55. let ofType<'Out> : obj -> 'Out option = function | :? 'Out as x -> Some x | _ -> None
  56. let tryNullOfType<'Out>(x:obj) : 'Out option = x |> tryNull |> ofType<'Out>
  57.  
  58. let ofUnrelatedType<'In, 'Out> (x : 'In) = box x |> ofType<'Out>
  59. let isOfType<'a> (x:obj) = match x with | :? 'a -> true | _ -> false
  60. let orElse (second:'a option) (first:'a option) = match first with | Some(x) -> Some(x) | None -> match second with | Some(y) -> Some(y) | None -> None
  61. let tryFind (predicate:'a -> bool) (x:'a option) = match x with | Some(x) when predicate x -> Some(x) | _ -> None
  62. let orDefault (d:'a) (x:'a option) = match x with | Some(x) -> x | None -> d
  63. let ofRef (result:bool,byref:'a) = if result then Some(byref) else None
  64.  
  65. module Seq =
  66. let ofType<'Out> = Seq.choose (Option.ofType<'Out>)
  67. let ofUnrelatedType<'In, 'Out> : 'In seq -> 'Out seq = Seq.choose (Option.ofUnrelatedType<'In, 'Out>)
  68.  
  69. let tryLast (xs: 'a seq) = xs |> Seq.fold (fun _ x -> Some x) None
  70. let tryHead (xs:'a seq) =
  71. let ys = xs.GetEnumerator()
  72. if ys.MoveNext() then Some(ys.Current) else None
  73.  
  74.  
  75.  
  76. module BooleanOperations =
  77. let inline (<||>) (s1:Solid) (s2:Solid) = BooleanOperationsUtils.ExecuteBooleanOperation(s1,s2,BooleanOperationsType.Union)
  78. let inline (<->) (s1:Solid) (s2:Solid) = BooleanOperationsUtils.ExecuteBooleanOperation(s1,s2,BooleanOperationsType.Difference)
  79. let inline (<&&>) (s1:Solid) (s2:Solid) = BooleanOperationsUtils.ExecuteBooleanOperation(s1,s2,BooleanOperationsType.Intersect)
  80.  
  81. type CylinderDirection =
  82. | BasisX
  83. | BasisY
  84. | BasisZ
  85.  
  86.  
  87. let π = Math.PI
  88.  
  89. let getViewByName(name:string) (doc:Document) =
  90.  
  91. use xs = new FilteredElementCollector(doc)
  92. seq { for x in xs.OfClass(typeof<View>) -> x} |> Seq.ofUnrelatedType<Element,View> |> Seq.filter (fun x -> x.Name = name) |> Seq.tryHead
  93.  
  94. let getView3DByName(name:string) (doc:Document) =
  95. use xs = new FilteredElementCollector(doc)
  96. seq { for x in xs.OfClass(typeof<View3D>) -> x} |> Seq.ofUnrelatedType<Element,View3D> |> Seq.filter (fun x -> x.Name = name) |> Seq.tryHead
  97.  
  98. let get3DViewElementId(doc:Document) =
  99. use xs = new FilteredElementCollector(doc)
  100. seq { for x in xs.OfClass(typeof<ViewFamilyType>) -> x} |> Seq.ofUnrelatedType<Element,ViewFamilyType> |> Seq.filter (fun e -> e.Name = "3D View") |> Seq.tryHead |> Option.map (fun e -> e.Id)
  101.  
  102. let create3DView =
  103. memoize (fun (name:string) (doc:Document) ->
  104. let view3DId = get3DViewElementId(doc).Value
  105. let view = View3D.CreateIsometric(doc, view3DId)
  106. let viewOrientation3D = new ViewOrientation3D(XYZ(1.,-1.,-1.), XYZ(1.,1.,1.), XYZ(1.,1.,-2.))
  107. view.SetOrientation(viewOrientation3D)
  108. view.SaveOrientation()
  109. view.Name <- name
  110. view)
  111.  
  112.  
  113.  
  114. let createCenterBasedBox(center:XYZ, edgelength:float) =
  115. let halfedgelength = edgelength / 2.0
  116. let profileloops = List<CurveLoop>()
  117. let profileloop = new CurveLoop();
  118.  
  119. [|
  120. (-1.,-1.,-1.), (-1., 1.,-1.)
  121. (-1., 1.,-1.), ( 1., 1.,-1.)
  122. ( 1., 1.,-1.), ( 1.,-1.,-1.)
  123. ( 1.,-1.,-1.), (-1.,-1.,-1.)
  124. |] |> Array.iter (fun ((a,b,c),(x,y,z)) ->
  125. let h = halfedgelength
  126. profileloop.Append(Line.CreateBound(XYZ(center.X + (h*a), center.Y + (h*b), center.Z + (h*c)),
  127. XYZ(center.X + (h*x), center.Y + (h*y), center.Z + (h*z)))))
  128.  
  129.  
  130. profileloops.Add(profileloop)
  131. let extrusiondir = XYZ.BasisZ
  132. GeometryCreationUtilities.CreateExtrusionGeometry(profileloops, extrusiondir, edgelength)
  133.  
  134. let createCenterBasedSphere(center:XYZ, radius:float) =
  135. let frame = new Frame(center, XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ)
  136. let profileloops = List<CurveLoop>()
  137. let profileloop = new CurveLoop()
  138.  
  139. let cemiEllipse = Ellipse.Create(center, radius, radius, XYZ.BasisX, XYZ.BasisZ, -π / 2., π / 2.)
  140. profileloop.Append(cemiEllipse)
  141. profileloop.Append(Line.CreateBound(XYZ(center.X, center.Y, center.Z + radius), XYZ(center.X, center.Y, center.Z - radius)))
  142. profileloops.Add(profileloop)
  143. GeometryCreationUtilities.CreateRevolvedGeometry(frame, profileloops, -π, π)
  144.  
  145.  
  146. let createCenterBasedCylinder(center:XYZ, bottomradius:double, height:float, cylinderdirections:CylinderDirection) =
  147. let halfheight = height / 2.
  148. let bottomcenter,topcenter =
  149. match cylinderdirections with
  150. | BasisX -> XYZ(center.X - halfheight, center.Y, center.Z),XYZ(center.X + halfheight, center.Y, center.Z)
  151. | BasisY -> XYZ(center.X, center.Y - halfheight, center.Z),XYZ(center.X, center.Y + halfheight, center.Z)
  152. | BasisZ -> XYZ(center.X, center.Y, center.Z - halfheight),XYZ(center.X, center.Y, center.Z + halfheight)
  153. let sweepPath = new CurveLoop()
  154. sweepPath.Append(Line.CreateBound(bottomcenter, topcenter))
  155.  
  156. let profileloops = List<CurveLoop>()
  157. let profileloop = new CurveLoop()
  158. let cemiEllipse1 =
  159. Ellipse.Create(bottomcenter, bottomradius, bottomradius,
  160. (if cylinderdirections = BasisX then XYZ.BasisY else XYZ.BasisX),
  161. (if cylinderdirections = BasisZ then XYZ.BasisY else XYZ.BasisZ),
  162. -π, 0.)
  163. let cemiEllipse2 =
  164. Ellipse.Create(bottomcenter, bottomradius, bottomradius,
  165. (if cylinderdirections = BasisX then XYZ.BasisY else XYZ.BasisX),
  166. (if cylinderdirections = BasisZ then XYZ.BasisY else XYZ.BasisZ),
  167. 0., π)
  168.  
  169. profileloop.Append(cemiEllipse1)
  170. profileloop.Append(cemiEllipse2)
  171. profileloops.Add(profileloop)
  172. GeometryCreationUtilities.CreateSweptGeometry(sweepPath,0,0., profileloops)
  173.  
  174. let mutable private schemaId = Option<int>.None
  175.  
  176. let paintSolid(s:Solid, viewName:string, doc:Document) =
  177. let view = create3DView viewName doc
  178. let sfm =
  179. match SpatialFieldManager.GetSpatialFieldManager(view) |> Option.ofNullable with
  180. | Some(x) -> x
  181. | None -> SpatialFieldManager.CreateSpatialFieldManager(view,1)
  182.  
  183. let getSchema() =
  184. let resultSchema1 = new AnalysisResultSchema("PaintedSolid" + viewName, "Description")
  185.  
  186. let displayStyle = AnalysisDisplayStyle.CreateAnalysisDisplayStyle(doc, "Real_Color_Surface" + viewName,
  187. new AnalysisDisplayColoredSurfaceSettings(),
  188. new AnalysisDisplayColorSettings(),
  189. new AnalysisDisplayLegendSettings())
  190.  
  191. resultSchema1.AnalysisDisplayStyleId <- displayStyle.Id
  192.  
  193. sfm.RegisterResult(resultSchema1)
  194.  
  195. let sId =
  196. match schemaId with
  197. | None ->
  198. let sId = getSchema()
  199. schemaId <- Some(sId)
  200. sId
  201. | Some(x) when not (sfm.GetRegisteredResults().Contains(x)) ->
  202. let sId = getSchema()
  203. schemaId <- Some(sId)
  204. sId
  205. | Some(x) -> x
  206.  
  207.  
  208.  
  209. //sfm.GetRegisteredResults()
  210.  
  211. for face in s.Faces do
  212. let idx = sfm.AddSpatialFieldPrimitive(face,Transform.Identity)
  213. let compteValueAtPointForFace(face:Face,measurementNo:int) : (UV[]*ValueAtPoint[]) =
  214. let bb = face.GetBoundingBox()
  215. [|
  216. for u in seq {bb.Min.U .. (bb.Max.U - bb.Min.U) .. bb.Max.U + 0.0000001 } do
  217. for v in seq {bb.Min.V .. (bb.Max.V - bb.Min.V) .. bb.Max.V + 0.0000001} do // Note original code devides by one which is weird
  218. let uvPnt = UV(u,v)
  219. let faceXYZ = face.Evaluate(uvPnt)
  220. let valPnt = new ValueAtPoint([|for ii = 1 to measurementNo do yield faceXYZ.DistanceTo(XYZ.Zero) * (float ii)|])
  221. yield (uvPnt,valPnt)
  222. |] |> fun xs -> (xs |> Array.map fst),(xs |> Array.map snd)
  223.  
  224.  
  225. let (uvPts,valList) = compteValueAtPointForFace(face,1)
  226. let pnts = new FieldDomainPointsByUV(uvPts)
  227. let vals = new FieldValues(valList)
  228. sfm.UpdateSpatialFieldPrimitive(idx,pnts, vals, sId)
  229.  
  230. open BooleanOperations
  231.  
  232. let zero = XYZ.Zero
  233. let xaxis = CylinderDirection.BasisX
  234. let yaxis = CylinderDirection.BasisY
  235. let zaxis = CylinderDirection.BasisZ
  236.  
  237. let box(p,size) = createCenterBasedBox(p, size)
  238. let sphere(p,r) = createCenterBasedSphere(p, r)
  239. let cylinder(p,radius,length,direction) = createCenterBasedCylinder(p, radius, length, direction)
  240.  
  241. let union y x = x <||> y
  242. let difference y x = x <-> y
  243. let intersect y x = x <&&> y
  244. let paint doc s = paintSolid(s, "CSGTree", doc)
  245.  
  246. module Mantis =
  247. let transaction (f:Document->unit) =
  248. Mantis.run (fun app ->
  249. let document = app.ActiveUIDocument.Document
  250. let tran = new Transaction(document, "GeometryCreation_BooleanOperation");
  251. tran.Start() |> ignore
  252. f document
  253. tran.Commit() |> ignore
  254. )
  255.  
  256. Mantis.transaction (fun doc ->
  257. sphere(zero,20.)
  258. |> intersect (box(zero,25.))
  259. |> difference
  260. ([
  261. cylinder(zero, 5., 40., xaxis)
  262. cylinder(zero, 5., 40., yaxis)
  263. cylinder(zero, 5., 40., zaxis)
  264. ] |> Seq.reduce union)
  265. |> paint doc
  266. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement