Duplicators
Updated 05 Apr 2018
|
Upper levels: - QuArK Information Base - 3. Advanced customization |
3.8. Duplicators |
[ | - - ]
Duplicators are 'abstract' QuArK-only mapobjects that generate ordinary mapobjects (brushes, entities, patches) from data. Their original use was to make copies of things, whence the name; the data consisted of the brushes and entities to be copied, plus some specifics on the duplicator, such as how many to make, their offsets, etc. When did Armin realize that they could do more than make copies? Probably from the start, but anyway the patch and brush-curve builders, wall extruder and even the threepoint plane are duplicators that don't make copies, but use data of a more abstract nature, such as the box that a curve will be contained in. Since the usual purpose of a duplicator is to construct some mapobjects, its most important method is its buildimages method, which takes some parameters and produces a list consisting of the mapobjects that will be produced. The parameters are 'self', and `singleimage', which is only relevant when the duplicator is being used to make multiple copies. It is set to None unless the method is being called to dissociate the images of the duplicator, in which case the duplicator is called once for each copy with singleimage set to the series number of the copy, starting with 0. This can make coding certain kinds of things rather complicated, since when singleimage is none, buildimages needs to loop, and when it's set to a number, it doesn't, but the result is that when the images are dissociated, each copy gets located in its own individual group. The actual calling of the buildimages method is done by the Delphi in duplicator.pas, by methods I don't understand. The fundamental duplicator classes and methods are defined in quarkpy.duplicator.py, and are exploited so as to produce most of the ordinary copying duplicators in plugins.mapdups.py. The base class is DuplicatorManager, with the following methods:
Duplicators that make copies are however mostly descendents of StandardDuplicator, which, unfortunately for people who want to learn how the code works, gotten monstrously complicated due to the series trigger-targeting, progressive linear mapping and other facilities that got engineered in. So here are some of the major methods as they were in a simpler age end of June, 2000): def readvalues(self): self.origin = self.dup.origin if self.origin is None: self.origin = quarkx.vect(0,0,0) s = self.dup["offset"] if s: self.offset = quarkx.vect(s) else: self.offset = None self.matrix = None The 'do' method applies the changes to be made to the item. Each change is w.r.t. the previously made copy. def do(self, item): "Default code to apply a one-step operation on 'item'." if self.offset: item.translate(self.offset) if self.matrix: item.linear(self.origin, self.matrix) return [item] def buildimages(self, singleimage=None): try: self.readvalues() except: print "Note: Invalid Duplicator Specific/Args." return list = self.sourcelist() newobjs = [] try: count = int(self.dup["count"]) except: count = 1 for i in range(count): self.imagenumber = i # the following line : # - makes copies of the items in "list"; # - calls "self.do" for the copies; # - puts the results of these calls into a list; # - removes all None objects; # - and stores the new list back in "list". list = reduce(lambda x,y: x+y, map(lambda item, fn=self.do: fn(item.copy()), list), []) if (singleimage is None) or (i==singleimage): newobjs = newobjs + list del self.imagenumber return newobjs The remaining code is concered with generating handles, one for the duplicator and one for each image-position, and a clever scheme for changing the offset value by dragging the handles around. This is done in the drag method of DupOffsetHandle, the idea being that the difference between the old and new handle positions (v2-v1) is used to operate on the duplicator's specifics (the CenterHandle code sets the duplicator as the .centerof value). Finally a good number of duplicators are defined in plugins.mapduplicators.py; these derived duplicator classes mostly work by reading in or setting matrices, although one has a special 'do' method. |
Copyright (c) 2022, GNU General Public License by The QuArK (Quake Army Knife) Community - https://quark.sourceforge.io/ |
[ Top - ] | -