Line data Source code
1 : # TODO: convert? / copyas
2 :
3 : """
4 : src = createmesh(...)
5 : dst = createmesh(...) # possibly typeof(src) != typeof(dst)
6 :
7 : dst = copy!(dst, src)
8 :
9 : Copy mesh `src` into `dst` and return `dst`. (Any prior content of
10 : `dst` is removed.)
11 :
12 :
13 : Source `src` and destination `dst` are both [`Mesh`](@ref)` but may be
14 : of different type (different type parameters, i.e., different
15 : attributes).
16 :
17 : This method copies the state of `src` including the "used" state of
18 : elements:" `src` and `dst` share the same connectivity and respective
19 : elements share identical handles.
20 :
21 : !!! note
22 : For equal types of `src` and `dst`, `copy!` is equivalent to
23 : [`clone`](@ref) but less efficient.
24 :
25 : This method Copies only attributes that are *enabled* for both, `src`
26 : and `dst`.
27 :
28 : !!! tip
29 : Use `dst = copy!(similar(template), src)` to create a copy
30 : of `src` of type `typeof(template)`.
31 :
32 : See also [`copytessellation!`](@ref), [`copyattrs!`](@ref)
33 : """
34 1 : function Base.copy!(dst::Mesh{Vd, Fd, Hd, Ed},
35 : src::Mesh{Vs, Fs, Hs, Es}) where {Vd, Fd, Hd, Ed, Vs, Fs, Hs, Es}
36 1 : copytessellation!(dst, src)
37 1 : copyattrs!(dst, src)
38 1 : dst
39 : end
40 :
41 : """
42 : src = createmesh(...)
43 : dst = createmesh(...) # possibly typeof(src) != typeof(dst)
44 :
45 : copytessellation!(dst, src) # === dst
46 :
47 : Copy tessellation ("connectivity", i.e., vertices and faces *without*
48 : attributes), of source mesh `src` to destination mesh `dst` and return
49 : `dst`. (Any prior content of `dst` is removed.)
50 :
51 : Source `src` and destination `dst` are both [`Mesh`](@ref)` but may be
52 : of different type (different type parameters, i.e., different
53 : attributes).
54 :
55 : This method copies the state of `src` including the "used" state of
56 : elements:" `src` and `dst` share the same connectivity and respective
57 : elements share identical handles.
58 :
59 : See also [`copy!`](@ref), [`copyattrs!`](@ref)
60 : """
61 2 : function copytessellation!(dst::Mesh{Vd, Fd, Hd, Ed},
62 : src::Mesh{Vs, Fs, Hs, Es}) where {Vd, Fd, Hd, Ed, Vs, Fs, Hs, Es}
63 :
64 2 : vsrc = vattr(src)
65 2 : fsrc = fattr(src)
66 2 : hsrc = hattr(src)
67 2 : esrc = eattr(src)
68 :
69 2 : vdst = vattr(dst)
70 2 : fdst = fattr(dst)
71 2 : hdst = hattr(dst)
72 2 : edst = eattr(dst)
73 :
74 2 : resizeattr!(attrs(vdst), n_total(vsrc))
75 2 : resizeattr!(attrs(fdst), n_total(fsrc))
76 3 : resizeattr!(attrs(hdst), 2n_total(esrc))
77 3 : resizeattr!(attrs(edst), n_total(esrc))
78 :
79 4 : flags(vdst).a .= flags(vsrc).a
80 3 : flags(fdst).a .= flags(fsrc).a
81 : # Note: no flags for H
82 3 : flags(edst).a .= flags(esrc).a
83 :
84 4 : link(vdst).a .= link(vsrc).a
85 3 : link(fdst).a .= link(fsrc).a
86 3 : link(hdst).a .= link(hsrc).a
87 : # Note: no link for E
88 :
89 2 : PMeshAttributes.update_used!(vdst, nv(src), Val(:absolute))
90 2 : PMeshAttributes.update_used!(fdst, nf(src), Val(:absolute))
91 : # Note: no count for H: #H == 2#E
92 2 : PMeshAttributes.update_used!(edst, ne(src), Val(:absolute))
93 :
94 2 : dst
95 : end
96 :
97 1 : function copyattrs!(dst::Mesh{Vd, Fd, Hd, Ed},
98 : src::Mesh{Vs, Fs, Hs, Es}) where {Vd, Fd, Hd, Ed, Vs, Fs, Hs, Es}
99 :
100 1 : copyvattrs!(dst, src)
101 1 : copyfattrs!(dst, src)
102 1 : copyhattrs!(dst, src)
103 1 : copyeattrs!(dst, src)
104 :
105 1 : dst
106 : end
107 :
108 : """
109 : copyattrs(dst, src)
110 :
111 : Copy user-defined vertex, face, half-edge and edge attributes from
112 : mesh `src` to `dst` and return `dst`.
113 :
114 : !!! warning "precondition"
115 : Requires identical tessellation of `src` and `dst`: call `copyattrs!`
116 : *after* [`copytessellation!`]!
117 :
118 : !!! note
119 : Copies only attributes that are *enabled* for both, `src` and `dst`.
120 : Also, internal attributes that define the element state (`_flags`) or
121 : connectivity (`_link`) are ignored.
122 :
123 : Utility:
124 :
125 : copyattrs(dst::ManagedAttributes, src::ManagedAttributes)
126 :
127 : Helper that copies `PMeshAttributes.ManagedAttributes` attributes
128 : from `src` to `dst`.
129 :
130 : !!! warning "precondition"
131 : Attributes must have equal length (`n_total`).
132 :
133 : See also [`copytessellation!`](@ref), [`copyattrs!`](@ref),
134 : [`copyvattrs!`](@ref), [`copyfattrs!`](@ref), [`copyhattrs!`](@ref),
135 : [`copyeattrs!`](@ref)
136 : """
137 6 : function copyattrs!(dst::ManagedAttributes, src::ManagedAttributes)
138 12 : for (name, b) in attrdict(attrs(dst))
139 17 : (name != :_link) || continue
140 17 : (name != :_flags) || continue
141 :
142 7 : isenabled(b) || continue
143 :
144 7 : hasattr(attrs(src), name) || continue
145 :
146 7 : a = attrs(src, name)
147 7 : isenabled(a) || continue
148 :
149 7 : @assert length(b.a) == length(a.a) "prior copytessellation!"
150 :
151 12 : b.a .= a.a
152 17 : end
153 :
154 : end
155 :
156 : """
157 : Copy vertex attributes, see [`copyattrs!`](@ref)
158 : """
159 2 : copyvattrs!(dst::Mesh, src::Mesh) = copyattrs!(vattr(dst), vattr(src))
160 :
161 : """
162 : Copy face attributes, see [`copyattrs!`](@ref)
163 : """
164 2 : copyfattrs!(dst::Mesh, src::Mesh) = copyattrs!(fattr(dst), fattr(src))
165 :
166 : """
167 : Copy half-edge attributes, see [`copyattrs!`](@ref)
168 : """
169 1 : copyhattrs!(dst::Mesh, src::Mesh) = copyattrs!(hattr(dst), hattr(src))
170 :
171 : """
172 : Copy edge attributes, see [`copyattrs!`](@ref)
173 : """
174 1 : copyeattrs!(dst::Mesh, src::Mesh) = copyattrs!(eattr(dst), eattr(src))
175 :
176 : """
177 : copy!(dst, src, handles)
178 :
179 : Copy all attributes defined by `handles` from source `src` to
180 : destination `dst`.
181 :
182 : !!! warning "preconditions"
183 : Require attributes for same mesh elemets, i.e., `dst` and `src`
184 : are both vertex, face, half-edge or edge attributes.
185 :
186 : !!! note
187 : You copy attributes from a different meshe: `dst` and `src` are
188 : not required to be attributes of the same mesh. *However*,
189 : `handles` need to be valid for both.
190 :
191 : !!! note
192 : `src` may also be a mapped attribute (see [Virtual attributes](@ref)
193 : and `PMeshAttributes`).
194 :
195 : # Example
196 :
197 : x1 = vattr(mesh1, Val(:x))
198 : x2 = vattr(mesh2, Val(:x))
199 :
200 : @assert collect(vertices(mesh1)) == collect(vertices(mesh2))
201 :
202 : copy!(x1, x2, vertices(mesh1))
203 :
204 : dblx2 = map(x -> 2x, x2)
205 : copy!(x1, dblx2, vertices(mesh1)) # mapped attribute
206 :
207 : See also [`map!`](@ref)
208 : """
209 0 : function Base.copy!(dst::Attribute{T, Hnd{I}},
210 : src::Attribute{T, Hnd{I}}, hs) where {T, I}
211 0 : for h in hs
212 0 : dst[h] = src[h]
213 0 : end
214 :
215 0 : dst
216 : end
217 :
218 1 : function Base.copy!(dst::Attribute{Td, Hnd{I}},
219 : src::PMeshAttributes.MappedAttribute{F, Ts, Hnd{I}},
220 : hs) where {F, Td, Ts, I}
221 2 : for h in hs
222 6 : dst[h] = src[h] :: Td
223 11 : end
224 :
225 1 : dst
226 : end
227 :
228 : """
229 : map!(f, dst, src, handles)
230 :
231 : Map and copy all attributes defined by `handles` from source `src` to
232 : destination `dst`.
233 :
234 : This is short for
235 :
236 : copy!(dst, map(f, src), handles)
237 :
238 : See also [`copy!`](@ref), [Virtual attributes](@ref)
239 : """
240 1 : Base.map!(f,
241 : dst::Attribute{Td, Hnd{I}},
242 : src::Attribute{Ts, Hnd{I}}, hs...) where {Td, Ts, I} =
243 : copy!(dst, map(f, src), hs...)
|