-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathVectorDisplacementMapOp.cs
154 lines (118 loc) · 4.51 KB
/
VectorDisplacementMapOp.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright (c) Ryan Schmidt ([email protected]) - All Rights Reserved
// Unauthorized copying of this file, via any medium is strictly prohibited. Proprietary and confidential.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using g3;
namespace gs
{
/// <summary>
/// This Op outputs an explicit VectorDisplacement map on the input mesh.
/// User explicitly sets the displacement values via UpdateMap()
/// </summary>
public class VectorDisplacementMapOp : BaseSingleOutputModelingOperator, IVectorDisplacementSourceOp
{
protected VectorDisplacement Displacement;
VectorDisplacement set_displacement;
bool have_set_displacement = false;
public virtual void UpdateMap(VectorDisplacement update)
{
lock (set_displacement) {
set_displacement.Set(update);
have_set_displacement = true;
}
base.invalidate();
}
/// <summary>
/// Returns copy of current displacement map. thread-safe.
/// </summary>
public virtual VectorDisplacement GetMapCopy()
{
VectorDisplacement map = new VectorDisplacement();
lock (Displacement) {
map.Set(Displacement);
}
return map;
}
IMeshSourceOp mesh_source;
public IMeshSourceOp MeshSource {
get { return mesh_source; }
set {
if (mesh_source != null)
mesh_source.OperatorModified -= on_source_modified;
mesh_source = value;
if (mesh_source != null)
mesh_source.OperatorModified += on_source_modified;
base.invalidate();
}
}
public VectorDisplacementMapOp(IMeshSourceOp meshSource = null)
{
Displacement = new VectorDisplacement();
set_displacement = new VectorDisplacement();
if ( meshSource != null )
MeshSource = meshSource;
}
protected virtual void on_source_modified(ModelingOperator op)
{
base.invalidate();
}
public virtual void Update()
{
base.begin_update();
if ( MeshSource == null )
throw new Exception("VectorDisplacementMapOp: must set valid MeshSource to compute!");
IMesh imesh = MeshSource.GetIMesh();
if (imesh.HasVertexNormals == false)
throw new Exception("VectorDisplacementMapOp: input mesh does not have surface normals...");
if (imesh is DMesh3 == false)
throw new Exception("VectorDisplacementMapOp: in current implementation, input mesh must be a DMesh3. Ugh.");
DMesh3 mesh = imesh as DMesh3;
lock(Displacement) {
if (have_set_displacement) {
lock (set_displacement) {
if (set_displacement.Count == mesh.MaxVertexID)
Displacement.Set(set_displacement);
have_set_displacement = false;
}
} else if ( Displacement.Count != mesh.MaxVertexID ) {
Displacement.Clear();
Displacement.Resize(mesh.MaxVertexID);
}
}
base.complete_update();
}
public IVectorDisplacement GetDisplacement() {
if (base.requires_update())
Update();
return Displacement;
}
}
/// <summary>
/// Extension of VectorDisplacementMapOp that supports auto-generating the map.
/// If .GenerateMap=true, then subclass must generate map
/// Otherwise, we return the static map, which can be edited (ie via sculpting)
/// </summary>
public abstract class ParametricVectorDisplacementMapOp : VectorDisplacementMapOp
{
public ParametricVectorDisplacementMapOp(IMeshSourceOp meshSource = null) : base(meshSource)
{
}
bool generate_map = true;
public bool GenerateMap {
get { return generate_map; }
set { generate_map = value; base.invalidate(); }
}
public override void Update()
{
if (generate_map) {
Update_GenerateMap();
} else {
base.Update();
}
}
// subclass implements this to generate map
protected abstract void Update_GenerateMap();
}
}