Jump to content

Catmull–Clark subdivision surface: Difference between revisions

m
syntax highlighting fixup automation
mNo edit summary
m (syntax highlighting fixup automation)
Line 46:
[[file:catmull-C.png|center]]
Only the subdivision part. The [[Catmull–Clark_subdivision_surface/C|full source]] is way too long to be shown here. Lots of macros, you'll have to see the full code to know what's what.
<langsyntaxhighlight lang=c>vertex face_point(face f)
{
int i;
Line 138:
}
return nm;
}</langsyntaxhighlight>
 
=={{header|Go}}==
Line 146:
 
See the original version for full comments.
<langsyntaxhighlight lang=go>package main
 
import (
Line 431:
fmt.Printf("%2d\n", f)
}
}</langsyntaxhighlight>
 
{{out}}
Line 489:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang=haskell>{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
 
Line 799:
 
main :: IO ()
main = putStr . pShowSimpleMesh $ subdivide testCube</langsyntaxhighlight>
{{out}}
<pre>Vertices:
Line 856:
=={{header|J}}==
 
<langsyntaxhighlight lang=j>avg=: +/ % #
 
havePoints=: e."1/~ i.@#
Line 878:
msh=. (,c0+mesh),.(,e0+edges i. meshEdges),.((#i.)~/$mesh),.,e0+_1|."1 edges i. meshEdges
msh;pts
)</langsyntaxhighlight>
 
Example use:
 
<langsyntaxhighlight lang=j>NB.cube
points=: _1+2*#:i.8
mesh=: 1 A."1 I.(,1-|.)8&$@#&0 1">4 2 1
Line 914:
│ │ 0.555556 0.555556 _0.555556│
│ │ 0.555556 0.555556 0.555556│
└──────────┴─────────────────────────────┘</langsyntaxhighlight>
 
=={{header|Julia}}==
<langsyntaxhighlight lang=julia>using Makie, Statistics
 
# Point3f0 is a 3-tuple of 32-bit floats for 3-dimensional space, and all Points are 3D.
Line 1,062:
 
println("Press Enter to continue", readline())
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Line 1,068:
The function relies on three externally defined general functionality functions:
 
<langsyntaxhighlight lang=Mathematica>subSetQ[large_,small_] := MemberQ[large,small]
subSetQ[large_,small_List] := And@@(MemberQ[large,#]&/@small)
 
containing[groupList_,item_]:= Flatten[Position[groupList,group_/;subSetQ[group,item]]]
 
ReplaceFace[face_]:=Transpose[Prepend[Transpose[{#[[1]],face,#[[2]]}&/@Transpose[Partition[face,2,1,1]//{#,RotateRight[#]}&]],face]]</langsyntaxhighlight>
subSetQ[small,large] is a boolean test for whether small is a subset of large. Note this is not a general purpose implimentation and only serves this purpose under the constrictions of the following program.
 
Line 1,083:
 
 
<langsyntaxhighlight lang=Mathematica>CatMullClark[{Points_,faces_}]:=Block[{avgFacePoints,avgEdgePoints,updatedPoints,newEdgePoints,newPoints,edges,newFaces,weights,pointUpdate,edgeUpdate,newIndex},
edges = DeleteDuplicates[Flatten[Partition[#,2,1,-1]&/@faces,1],Sort[#1]==Sort[#2]&];
avgFacePoints=Mean[Points[[#]]] &/@ faces;
Line 1,110:
newFaces = Flatten[Map[newIndex[#,{Points,edges,faces}]&,ReplaceFace/@faces,{-2}],1];
{newPoints,newFaces}
]</langsyntaxhighlight>
 
The implimentation can be tested with polygons with and without holes by using the polydata
<langsyntaxhighlight lang=Mathematica>{points,faces}=PolyhedronData["Cube",{"VertexCoordinates","FaceIndices"}];
 
Function[iteration,
Graphics3D[(Polygon[iteration[[1]][[#]]]&/@iteration[[2]])]
]/@NestList[CatMullClark,{points,faces},3]//GraphicsRow</langsyntaxhighlight>
[[File:CAM noholes 1.png]]
 
For a surface with holes the resulting iterative subdivision will be:
<langsyntaxhighlight lang=Mathematica>faces = Delete[faces, 6];
Function[iteration, Graphics3D[
(Polygon[iteration[[1]][[#]]] & /@ iteration[[2]])
]] /@ NestList[CatMullClark, {points, faces}, 3] // GraphicsRow</langsyntaxhighlight>
[[File:CAM holes 1.png]]
 
Line 1,132:
{{trans|Go}}
{{trans|Python}}
<langsyntaxhighlight lang=Nim>import algorithm
import tables
 
Line 1,487:
s.add(fmt"{n:2d}")
s.add(']')
echo s</langsyntaxhighlight>
 
{{out}}
Line 1,552:
In the [[Catmull–Clark subdivision surface/OCaml|sub-page]] there is also a program in OCaml+OpenGL which displays a cube subdivided 2 times with this algorithm.
 
<langsyntaxhighlight lang=ocaml>open Dynar
 
let add3 (x1, y1, z1) (x2, y2, z2) (x3, y3, z3) =
Line 1,687:
(Dynar.to_array da_points,
Dynar.to_array new_faces)
;;</langsyntaxhighlight>
=== Another implementation ===
Another implementation which should work with holes, but has only been tested on a cube
{{works with|OCaml|4.02+}}
<langsyntaxhighlight lang=OCaml>type point = { x: float; y : float; z : float }
let zero = { x = 0.0; y = 0.0; z = 0.0 }
let add a b = { x = a.x+.b.x; y = a.y+.b.y; z = a.z+.b.z }
Line 1,764:
Face [c 0 0 0; c 0 1 0; c 1 1 0; c 1 0 0]; Face [c 0 0 1; c 0 1 1; c 1 1 1; c 1 0 1] ] in
show_faces cube;
show_faces (catmull_clark cube)</langsyntaxhighlight>
with output:
<pre>surface {
Line 1,803:
=={{header|Phix}}==
{{trans|Go}}
<!--<langsyntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Catmull_Clark_subdivision_surface.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 2,020:
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">outputPoints</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">outputFaces</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),{</span><span style="color: #004600;">pp_IntFmt</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%2d"</span><span style="color: #0000FF;">})</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 2,076:
 
=={{header|Python}}==
<langsyntaxhighlight lang=python>
"""
 
Line 2,633:
graph_output(output_points, output_faces)
</syntaxhighlight>
</lang>
 
=={{header|Rust}}==
{{trans|Python}}
<langsyntaxhighlight lang=Rust>
pub struct Vector3 {pub x: f64, pub y: f64, pub z: f64, pub w: f64}
 
Line 2,921:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Tcl}}==
This code handles both holes and arbitrary polygons in the input data.
<langsyntaxhighlight lang=tcl>package require Tcl 8.5
 
# Use math functions and operators as commands (Lisp-like).
Line 3,046:
 
list [concat $newPoints $facepoints $edgepoints] $newFaces
}</langsyntaxhighlight>
 
The [[/Tcl Test Code|test code]] for this solution is available as well. The example there produces the following partial toroid output image:
Line 3,058:
{{libheader|Wren-math}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight lang=ecmascript>import "/dynamic" for Tuple, Struct
import "/sort" for Sort
import "/math" for Int
Line 3,327:
for (f in outputFaces) {
Fmt.aprint(f, 2, 0, "[]")
}</langsyntaxhighlight>
 
{{out}}
10,333

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.