HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SOP_BrushHairLen.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021
3  * Side Effects Software Inc. All rights reserved.
4  *
5  * Redistribution and use of Houdini Development Kit samples in source and
6  * binary forms, with or without modification, are permitted provided that the
7  * following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. The name of Side Effects Software may not be used to endorse or
11  * promote products derived from this software without specific prior
12  * written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
15  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17  * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  *----------------------------------------------------------------------------
26  */
27 
28 #ifndef __SOP_BrushHairLen__
29 #define __SOP_BrushHairLen__
30 
31 #include <SOP/SOP_Node.h>
32 #include <SOP/SOP_BrushBase.h>
33 
34 namespace HDK_Sample {
36 {
37 public:
38  SOP_BrushHairLen(OP_Network *net, const char *, OP_Operator *entry);
39  ~SOP_BrushHairLen() override;
40 
41  static OP_Node *myConstructor(OP_Network *net, const char *name,
42  OP_Operator *entry);
44 
45  /// This is the callback triggered when a BRUSHOP_CALLBACK is used:
46  void brushOpCallback(
47  GA_Offset pt,
48  const UT_Array<GA_Offset> *ptneighbour,
49  GA_Offset vtx,
50  const UT_Array<GA_Offset> *vtxneighbour,
51  float alpha,
52  GEO_Delta *delta) override;
53 
54 protected:
56 
57  /// These are the many & various methods used by BrushBase to
58  /// determine the current brush status. We can either hook them
59  /// up to parameters (via evalFloat) or hard code them. In this
60  /// case we have hard coded most.
61 
62  /// Public methods needed by MSS:
63 public:
64  /// Finds the geometry to do the intersection with.
65  const GU_Detail *getIsectGdp(fpreal t) override;
66 
67  /// If the action of the brush will change point positions,
68  /// we should set this to 1. We create geometry, but leave point
69  /// positions untouched.
70  int altersGeometry() const override
71  { return 0; }
72  /// We do attribute changes.
73  int altersColor() const override
74  { return 1; }
75  /// This gets the current radius of the brush, unmodulated by the
76  /// current pressure amount.
78  { return evalFloat("radius", 0, t); }
79  /// This gets the raw radius for the UV space.
81  { return evalFloat("uvradius", 0, t); }
82  /// This is how much the HITPRESSURE should affect the RADIUS.
83  fpreal RADIUSPRESSURE(fpreal /*t*/) override
84  { return 1.0f; }
85  /// The opacity, hardcoded to 1.0f, for a full replace
86  fpreal RAWOPACITY(fpreal /*t*/) override
87  { return 1.0f; }
88  fpreal OPACITYPRESSURE(fpreal /*t*/) override
89  { return 1.0f; }
90 
91  /// This is how far along the brush axis it will be able to paint.
92  /// We tie it directly to the raidus here.
93  fpreal DEPTH(fpreal t) override
94  { return evalFloat("radius", 0, t); }
95  fpreal HEIGHT(fpreal t) override
96  { return evalFloat("radius", 0, t); }
97  /// Whether to use depth clipping at all.
98  int USEDEPTH() override
99  { return 1; }
100  /// Whether to not paint across unconnected seams. We are using depth
101  /// clipping in this tool, so have it off.
102  int USECONNECTIVITY() override
103  { return 0; }
104 
105  /// This needs to map our OP_Menu into SOP_BrushOp. We leave this
106  /// to the C code.
107  SOP_BrushOp OP() override;
108 
109  /// Whether accumulate stencil is currently on. We keep it off.
110  int ACCUMSTENCIL() override
111  { return 0; }
112  /// Projection Type 1 is orient to surface, 0 is to use it flat on.
113  /// We hard code it to flat on.
114  int PROJECTIONTYPE() override
115  { return 0; }
116  /// In realtime mode, all changes are applied immediately to the
117  /// gdp, rather than being stored in the CurrentDelta during a brush
118  /// stroke. Some types of brushing require this behaviour implicitly.
119  int REALTIME() override
120  { return 1; }
121  /// This returns a SOP_BrushShape. We hardcode to circle.
122  int SHAPE(fpreal /*t*/) override
123  { return SOP_BRUSHSHAPE_CIRCLE; }
124 
125  /// Protected methods needed by SOP_BrushBase:
126 protected:
127  /// This returns a GU_BrushMergeMode, defined in GU_Brush.h
128  /// We just use the standard replace.
129  int MERGEMODE() override
130  { return GU_BRUSHMERGEMODE_REPLACE; }
131 
132  /// Not used:
133  void SCRIPT(UT_String & /*s*/, fpreal /*t*/) override
134  { }
135 
136  /// These are used by deformation brush ops:
137  int AXIS() override
138  { return 0; }
139  fpreal USERX(fpreal /*t*/) override
140  { return 0.0f; }
141  fpreal USERY(fpreal /*t*/) override
142  { return 0.0f; }
143  fpreal USERZ(fpreal /*t*/) override
144  { return 0.0f; }
145 
146  /// These query the current raystate. We read off the cached values...
147  fpreal RAYORIENTX(fpreal /*t*/) override
148  { return myRayOrient.x(); }
149  fpreal RAYORIENTY(fpreal /*t*/) override
150  { return myRayOrient.y(); }
151  fpreal RAYORIENTZ(fpreal /*t*/) override
152  { return myRayOrient.z(); }
153  fpreal RAYHITX(fpreal /*t*/) override
154  { return myRayHit.x(); }
155  fpreal RAYHITY(fpreal /*t*/) override
156  { return myRayHit.y(); }
157  fpreal RAYHITZ(fpreal /*t*/) override
158  { return myRayHit.z(); }
159  fpreal RAYHITU(fpreal /*t*/) override
160  { return myRayHitU; }
161  fpreal RAYHITV(fpreal /*t*/) override
162  { return myRayHitV; }
163  fpreal RAYHITW(fpreal /*t*/) override
164  { return myRayHitW; }
165  fpreal RAYHITPRESSURE(fpreal /*t*/) override
166  { return myRayHitPressure; }
167  int PRIMHIT(fpreal /*t*/) override
168  { return myPrimHit; }
169  int PTHIT(fpreal /*t*/) override
170  { return myPtHit; }
171  int EVENT() override
172  { return myEvent; }
173 
174  /// These query the current "colours" of the brush...
175  /// F is for foreground, B, for background. Up to a 3 vector is
176  /// possible in the order R, G, B.
177  /// If USE_FOREGROUND is true, the F will be used, otherwise B.
178  bool USE_FOREGROUND() override
179  { return myUseFore; }
180  fpreal FGR(fpreal t) override
181  { return evalFloat("flen", 0, t); }
182  fpreal FGG(fpreal /*t*/) override
183  { return 0.0f; }
184  fpreal FGB(fpreal /*t*/) override
185  { return 0.0f; }
186  fpreal BGR(fpreal t) override
187  { return evalFloat("blen", 0, t); }
188  fpreal BGG(fpreal /*t*/) override
189  { return 0.0f; }
190  fpreal BGB(fpreal /*t*/) override
191  { return 0.0f; }
192 
193  /// These control the shape of the nib. We have hard coded
194  /// most of them...
195  /// What percentage of the radius to devote to the fall off curve.
196  fpreal SOFTEDGE(fpreal /*t*/) override
197  { return 1.0f; }
198  /// Which metaball kernel to use as the fall off curve.
199  void KERNEL(UT_String &str, fpreal /*t*/) override
200  { str = "Elendt"; }
201  /// How to determine the upvector, unnecessary with circular brushes.
202  int UPTYPE(fpreal /*t*/) override
203  { return 0; }
204  fpreal UPX(fpreal /*t*/) override
205  { return 0.0f; }
206  fpreal UPY(fpreal /*t*/) override
207  { return 0.0f; }
208  fpreal UPZ(fpreal /*t*/) override
209  { return 0.0f; }
210 
211  /// Alpha noise in the paper space
212  fpreal PAPERNOISE(fpreal /*t*/) override
213  { return 0.0f; }
214  /// Alpha noise in the brush space
215  fpreal SPLATTER(fpreal /*t*/) override
216  { return 0.0f; }
217  /// Name of the bitmap to use if bitmap brush is on, which it isn't.
218  void BITMAP(UT_String & /*str*/, fpreal /*t*/) override
219  { }
220  /// Which channel of the bitmap brush should be used.
221  int BITMAPCHAN(fpreal /*t*/) override
222  { return 0; }
223  /// More hard coded stuff directly from the Nib tab...
224  fpreal ANGLE(fpreal /*t*/) override
225  { return 0.0f; }
226  fpreal SQUASH(fpreal /*t*/) override
227  { return 1.0f; }
228  int DOSTAMPING() override
229  { return 0; }
230  int WRITEALPHA() override
231  { return 0; }
232  /// We explicitly override these parameters as we want the brush
233  /// to automatically edit our "hairlen" point attribute.
234  int OVERRIDECD() override
235  { return 1; }
236  void CDNAME(UT_String &str, fpreal /*t*/) override
237  { str = "hairlen"; }
238  /// As WRITEALPHA is off, this is irrelevant:
239  int OVERRIDEALPHA() override
240  { return 0; }
241  void ALPHANAME(UT_String & /*str*/, fpreal /*t*/) override
242  { }
243  /// For Comb style brushes, this preserves the normal length.
244  int PRESERVENML() override
245  { return 0; }
246  /// For Comb style brushes this allows overriding the normal attribute.
247  int OVERRIDENML() override
248  { return 0; }
249  void NMLNAME(UT_String & /*str*/, fpreal /*t*/) override
250  { }
251 
252  /// These methods are used to get the current symmetry operations
253  /// that are enabled with the brush. We don't use any of them here.
254  int DOREFLECTION() override
255  { return 0; }
256  int DOROTATION() override
257  { return 0; }
258  fpreal SYMMETRYDIRX(fpreal /*t*/) override
259  { return 0.0f; }
260  fpreal SYMMETRYDIRY(fpreal /*t*/) override
261  { return 0.0f; }
262  fpreal SYMMETRYDIRZ(fpreal /*t*/) override
263  { return 0.0f; }
264  fpreal SYMMETRYORIGX(fpreal /*t*/) override
265  { return 0.0f; }
266  fpreal SYMMETRYORIGY(fpreal /*t*/) override
267  { return 0.0f; }
268  fpreal SYMMETRYORIGZ(fpreal /*t*/) override
269  { return 0.0f; }
270  int SYMMETRYROT(fpreal /*t*/) override
271  { return 0; }
272  fpreal SYMMETRYDIST(fpreal /*t*/) override
273  { return 0.0f; }
274 
275  /// This determines if the Cd or Normal should be auto-added.
276  /// We have it off as we add it by hand in our cook.
277  int ADDATTRIB() override
278  { return 0; }
279  /// This determines if visualization will occur.
280  int VISUALIZE() override
281  { return 0; }
282  int VISTYPE() override
283  { return 0; }
284  fpreal VISLOW(fpreal /*t*/) override
285  { return 0.0f; }
286  fpreal VISHIGH(fpreal /*t*/) override
287  { return 1.0f; }
288  int VISMODE() override
289  { return 0; }
291  { return 1.0f; }
293  { return 1.0f; }
295  { return 1.0f; }
296 
297  /// This is used by capture brushes to determine if they should
298  /// normalize the weights.
299  int NORMALIZEWEIGHT() override
300  { return 0; }
301 
302  /// Should return true if this brush will affect capture regions.
303  int USECAPTURE() override
304  { return 0; }
305  /// Returns the capture region to brush for such brushes.
306  int CAPTUREIDX(fpreal /*t*/) override
307  { return 0; }
308 
309  /// These determine if the relevant parameters have changed. They are
310  /// often used to determine when to invalidate internal caches.
311 
312  /// hasStrokeChanged should return true if any of the setHit* were called,
313  /// as it will cause a new dab to be applied.
314  bool hasStrokeChanged(fpreal /*t*/) override
315  { return myStrokeChanged; }
316  /// This should return true if the style of the brush changed, specifically
317  /// the foreground or background colours. We test this trhough isParmDirty
318  /// in the C code.
319  bool hasStyleChanged(fpreal t) override;
320  /// This determines if the nib file changed. We don't have a nib file.
321  bool hasNibFileChanged(fpreal /*t*/) override
322  { return false; }
323  /// This returns true if any nib parameters (such as shape, etc) have
324  /// changed since the last cook.
325  bool hasNibLookChanged(fpreal /*t*/) override
326  { return false; }
327  /// This returns true if the type of accumulation mode changed.
328  bool hasAccumStencilChanged(fpreal /*t*/) override
329  { return false; }
330  /// This returns true if the capture index has changed.
331  bool hasCaptureIdxChanged(fpreal /*t*/) override
332  { return false; }
333  /// This return strue if the visualization range has changed.
334  bool hasVisrangeChanged(fpreal /*t*/) override
335  { return false; }
336 
337  /// If this returns true, the selection will be cooked as the
338  /// group. We don't want that, so return false.
339  bool wantsCookSelection() const override
340  { return false; }
341 
342  /// public methods used by MSS level to write to this level:
343  /// The usual brush ops (such as Paint, etc) will set parameters
344  /// with these values. We just cache them locally here.
345 public:
346  /// We are locking off accumulate stencil (ACCUMSTENCIL) so can
347  /// ignore attempts to turn it on.
348  void setAccumulateStencil(bool /*yesno*/) override {}
349  void setRayOrigin(const UT_Vector3 &orig, fpreal /*t*/) override
350  { myRayHit = orig; myStrokeChanged = true; forceRecook(); }
351  void setRayOrientation(const UT_Vector3 &orient, fpreal /*t*/) override
352  { myRayOrient = orient; myStrokeChanged = true; forceRecook(); }
353  void setHitPrimitive(int primidx, fpreal /*t*/) override
354  { myPrimHit = primidx; myStrokeChanged = true; forceRecook(); }
355  void setHitPoint(int ptidx, fpreal /*t*/) override
356  { myPtHit = ptidx; myStrokeChanged = true; forceRecook(); }
357  void setHitUVW(fpreal u, fpreal v, fpreal w, fpreal /*t*/) override
358  {
359  myRayHitU = u;
360  myRayHitV = v;
361  myRayHitW = w;
362  myStrokeChanged = true;
363  forceRecook();
364  }
365  void setHitPressure(fpreal pressure, fpreal /*t*/) override
366  { myRayHitPressure = pressure; myStrokeChanged = true; forceRecook(); }
368  { myEvent = event; myStrokeChanged = true; forceRecook(); }
369  /// This one must map from SOP_BrushOp into our own op menu.
370  /// Thus it is left to the C file.
371  void setBrushOp(SOP_BrushOp op) override;
372  /// As we are always returning CIRCLE for SHAPE(), we ignore
373  /// requests to change the brush shape.
374  void setBrushShape(SOP_BrushShape /*shape*/) override {}
375  /// As we are locking projection type to not orient to surface,
376  /// we can ignore these change requests (see PROJECTIONTYPE)
377  void setProjectionType(int /*projtype*/) override {}
378  void useForegroundColor() override
379  { myUseFore = true; }
380  void useBackgroundColor() override
381  { myUseFore = false; }
382  /// This is used by the eyedropper to write into the current colour
383  /// field.
384  void setCurrentColor(const UT_Vector3 &cd) override
385  {
386  setFloat(myUseFore ? "flen" : "blen", 0, 0, cd.x());
387  }
388 
389  /// This is used to update the radii from the state:
390  void setRadius(fpreal r, fpreal t) override
391  {
392  setFloat("radius", 0, t, r);
393  }
394  void setUVRadius(fpreal r, fpreal t) override
395  {
396  setFloat("uvradius", 0, t, r);
397  }
398 
399 protected:
400  /// This method handles the erase callback relevant to this type
401  /// of brush.
402  void doErase() override;
403 
404 private:
405  /// Here we cache the current ray hit values...
406  UT_Vector3 myRayOrient, myRayHit;
407  float myRayHitU, myRayHitV, myRayHitW;
408  float myRayHitPressure;
409  int myPrimHit;
410  int myPtHit;
411  int myEvent;
412  bool myUseFore;
413  bool myStrokeChanged;
414 
415 
416  /// These are cached for the brushop callback to know the attribute
417  /// indices.
418  bool myHairlenFound;
419  GA_RWHandleF myHairlenHandle;
420  fpreal myTime;
421 };
422 } // End HDK_Sample namespace
423 
424 #endif
fpreal SYMMETRYDIRZ(fpreal) override
bool wantsCookSelection() const override
fpreal SYMMETRYDIRY(fpreal) override
int PRIMHIT(fpreal) override
bool hasCaptureIdxChanged(fpreal) override
This returns true if the capture index has changed.
void setAccumulateStencil(bool) override
fpreal VISHIGH(fpreal) override
void setHitUVW(fpreal u, fpreal v, fpreal w, fpreal) override
GLuint const GLchar * name
Definition: glew.h:1814
void KERNEL(UT_String &str, fpreal) override
Which metaball kernel to use as the fall off curve.
GLclampf GLclampf GLclampf alpha
Definition: glew.h:1520
fpreal RAYHITU(fpreal) override
bool hasNibLookChanged(fpreal) override
fpreal FGG(fpreal) override
int altersColor() const override
We do attribute changes.
fpreal ZEROWEIGHTCOLOR_B() override
void setProjectionType(int) override
fpreal SYMMETRYORIGZ(fpreal) override
fpreal BGR(fpreal t) override
SOP_BrushOp OP() override
fpreal RAWRADIUS(fpreal t) override
OP_ERROR cookMySop(OP_Context &context) override
virtual void forceRecook(bool evensmartcache=true)
fpreal evalFloat(int pi, int vi, fpreal t) const
bool hasNibFileChanged(fpreal) override
This determines if the nib file changed. We don't have a nib file.
fpreal SOFTEDGE(fpreal) override
UT_ErrorSeverity
Definition: UT_Error.h:25
fpreal VISLOW(fpreal) override
fpreal HEIGHT(fpreal t) override
const GU_Detail * getIsectGdp(fpreal t) override
Public methods needed by MSS:
void setBrushShape(SOP_BrushShape) override
fpreal PAPERNOISE(fpreal) override
Alpha noise in the paper space.
bool hasAccumStencilChanged(fpreal) override
This returns true if the type of accumulation mode changed.
fpreal RAYORIENTX(fpreal) override
These query the current raystate. We read off the cached values...
const GLdouble * v
Definition: glew.h:1391
int OVERRIDEALPHA() override
As WRITEALPHA is off, this is irrelevant:
fpreal RAYHITPRESSURE(fpreal) override
void setBrushEvent(SOP_BrushEvent event) override
fpreal ANGLE(fpreal) override
More hard coded stuff directly from the Nib tab...
void setRayOrientation(const UT_Vector3 &orient, fpreal) override
bool hasStyleChanged(fpreal t) override
int CAPTUREIDX(fpreal) override
Returns the capture region to brush for such brushes.
GA_Size GA_Offset
Definition: GA_Types.h:639
fpreal ZEROWEIGHTCOLOR_G() override
fpreal RAWOPACITY(fpreal) override
The opacity, hardcoded to 1.0f, for a full replace.
SYS_FORCE_INLINE T & y()
Definition: UT_Vector3.h:513
bool hasVisrangeChanged(fpreal) override
This return strue if the visualization range has changed.
fpreal OPACITYPRESSURE(fpreal) override
void NMLNAME(UT_String &, fpreal) override
fpreal SYMMETRYDIRX(fpreal) override
int USECAPTURE() override
Should return true if this brush will affect capture regions.
int PTHIT(fpreal) override
fpreal RAWUVRADIUS(fpreal t) override
This gets the raw radius for the UV space.
void setUVRadius(fpreal r, fpreal t) override
fpreal BGB(fpreal) override
void setRadius(fpreal r, fpreal t) override
This is used to update the radii from the state:
fpreal BGG(fpreal) override
void SCRIPT(UT_String &, fpreal) override
Not used:
static OP_Node * myConstructor(OP_Network *net, const char *name, OP_Operator *entry)
fpreal USERY(fpreal) override
fpreal RAYHITV(fpreal) override
SYS_FORCE_INLINE T & z()
Definition: UT_Vector3.h:515
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1890
int AXIS() override
These are used by deformation brush ops:
int SYMMETRYROT(fpreal) override
fpreal USERZ(fpreal) override
SOP_BrushOp
Definition: SOP_BrushBase.h:38
void setCurrentColor(const UT_Vector3 &cd) override
int OVERRIDENML() override
For Comb style brushes this allows overriding the normal attribute.
int UPTYPE(fpreal) override
How to determine the upvector, unnecessary with circular brushes.
fpreal FGB(fpreal) override
GA_API const UT_StringHolder orient
fpreal UPZ(fpreal) override
int SHAPE(fpreal) override
This returns a SOP_BrushShape. We hardcode to circle.
fpreal SYMMETRYORIGY(fpreal) override
void setRayOrigin(const UT_Vector3 &orig, fpreal) override
int USEDEPTH() override
Whether to use depth clipping at all.
fpreal RAYHITY(fpreal) override
fpreal RAYORIENTY(fpreal) override
fpreal RAYHITZ(fpreal) override
static PRM_Template myTemplateList[]
cl_event event
Definition: glew.h:3695
int VISUALIZE() override
This determines if visualization will occur.
void CDNAME(UT_String &str, fpreal) override
void setFloat(int parmi, int vectori, fpreal t, fpreal value, PRM_AddKeyType add_key=PRM_AK_MARK_PENDING)
fpreal SYMMETRYDIST(fpreal) override
fpreal64 fpreal
Definition: SYS_Types.h:277
void setHitPrimitive(int primidx, fpreal) override
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
fpreal RAYHITW(fpreal) override
fpreal UPX(fpreal) override
fpreal DEPTH(fpreal t) override
fpreal RAYHITX(fpreal) override
SYS_FORCE_INLINE T & x()
Definition: UT_Vector3.h:511
int ACCUMSTENCIL() override
Whether accumulate stencil is currently on. We keep it off.
fpreal UPY(fpreal) override
fpreal ZEROWEIGHTCOLOR_R() override
fpreal SQUASH(fpreal) override
SOP_BrushEvent
Definition: SOP_BrushBase.h:30
fpreal RADIUSPRESSURE(fpreal) override
This is how much the HITPRESSURE should affect the RADIUS.
fpreal RAYORIENTZ(fpreal) override
int BITMAPCHAN(fpreal) override
Which channel of the bitmap brush should be used.
fpreal USERX(fpreal) override
SOP_BrushShape
Definition: SOP_BrushBase.h:62
void BITMAP(UT_String &, fpreal) override
Name of the bitmap to use if bitmap brush is on, which it isn't.
fpreal SYMMETRYORIGX(fpreal) override
bool hasStrokeChanged(fpreal) override
int PRESERVENML() override
For Comb style brushes, this preserves the normal length.
fpreal SPLATTER(fpreal) override
Alpha noise in the brush space.
void setHitPressure(fpreal pressure, fpreal) override
GLdouble GLdouble t
Definition: glew.h:1398
SOP_BrushHairLen(OP_Network *net, const char *, OP_Operator *entry)
fpreal FGR(fpreal t) override
void ALPHANAME(UT_String &, fpreal) override
int MERGEMODE() override
Protected methods needed by SOP_BrushBase:
void setBrushOp(SOP_BrushOp op) override
void setHitPoint(int ptidx, fpreal) override
int altersGeometry() const override
void brushOpCallback(GA_Offset pt, const UT_Array< GA_Offset > *ptneighbour, GA_Offset vtx, const UT_Array< GA_Offset > *vtxneighbour, float alpha, GEO_Delta *delta) override
This is the callback triggered when a BRUSHOP_CALLBACK is used: