├── .gitignore
├── .gitmodules
├── Info.plist
├── LICENSE
├── Makefile
├── Mesh.qlgenerator
└── Contents
│ ├── Info.plist
│ ├── MacOS
│ └── Mesh
│ └── libs
│ ├── libGL.1.dylib
│ ├── libOSMesa.8.dylib
│ ├── libX11-xcb.1.dylib
│ ├── libX11.6.dylib
│ ├── libXau.6.dylib
│ ├── libXdmcp.6.dylib
│ ├── libXext.6.dylib
│ └── libxcb.1.dylib
├── README.md
└── src
├── GeneratePreviewForURL.m
├── GenerateThumbnailForURL.m
├── main.c
├── render_to_buffer.cpp
└── render_to_buffer.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # use glob syntax.
2 | syntax: glob
3 | scripts/change_name.sh
4 | *.so
5 | *.so.[0123456789]
6 | *.so.[0123456789].[0123456789]
7 | *.o
8 | *.a
9 | *.dylib
10 | *~
11 | *CMakeFiles*
12 | .DS_Store
13 | *tags
14 | *.exe
15 | *.pdb
16 | *.sdf
17 | *.suo
18 | *.ilk
19 | *.log
20 | *.tlog
21 | Debug/
22 | Release/
23 | *.orig
24 | *.user
25 | *.vsp
26 | *.opensdf
27 | *.psess
28 | *.swp
29 | *.swo
30 | *.pyc
31 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "mesa"]
2 | path = mesa
3 | url = https://github.com/mesa3d/mesa.git
4 |
--------------------------------------------------------------------------------
/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 13E28
7 | CFBundleDevelopmentRegion
8 | English
9 | CFBundleDocumentTypes
10 |
11 |
12 | CFBundleTypeRole
13 | QLGenerator
14 | LSItemContentTypes
15 |
16 | public.3d-content
17 | com.mesh.mesh
18 | com.mesh.off
19 | com.mesh.ply
20 | com.mesh.stl
21 | com.mesh.wrl
22 |
23 |
24 |
25 | CFBundleExecutable
26 | Mesh
27 | CFBundleIdentifier
28 | com.mesh.quicklook
29 | CFBundleInfoDictionaryVersion
30 | 6.0
31 | CFBundleName
32 | Mesh
33 | CFBundleShortVersionString
34 | 1.0.2
35 | CFBundleVersion
36 | 1.0
37 | CFPlugInDynamicRegisterFunction
38 |
39 | CFPlugInDynamicRegistration
40 | NO
41 | CFPlugInFactories
42 |
43 | 8D269336-626C-4F43-903F-D2F6AE5C4976
44 | QuickLookGeneratorPluginFactory
45 |
46 | CFPlugInTypes
47 |
48 | 5E2D9680-5022-40FA-B806-43349622E5B9
49 |
50 | 8D269336-626C-4F43-903F-D2F6AE5C4976
51 |
52 |
53 | CFPlugInUnloadFunction
54 |
55 | DTCompiler
56 | com.apple.compilers.llvm.clang.1_0
57 | DTPlatformBuild
58 | 5B1008
59 | DTPlatformVersion
60 | GM
61 | DTSDKBuild
62 | 13C64
63 | DTSDKName
64 | macosx10.9
65 | DTXcode
66 | 0511
67 | DTXcodeBuild
68 | 5B1008
69 | LSApplicationCategoryType
70 |
71 | NSHumanReadableCopyright
72 | Copyright © 2015 Alec Jacobson
73 | QLNeedsToBeRunInMainThread
74 |
75 | QLPreviewHeight
76 | 405
77 | QLPreviewWidth
78 | 720
79 | QLSupportsConcurrentRequests
80 |
81 | QLThumbnailMinimumSize
82 | 10
83 | UTExportedTypeDeclarations
84 |
85 |
86 |
87 | UTTypeConformsTo
88 |
89 | public.data
90 |
91 | UTTypeDescription
92 | 3d tetrahedral mesh
93 | UTTypeIdentifier
94 | com.mesh.mesh
95 | UTTypeReferenceURL
96 | http://www.ann.jussieu.fr/frey/publications/RT-0253.pdf#page=33
97 | UTTypeTagSpecification
98 |
99 | public.filename-extension
100 |
101 | mesh
102 |
103 |
104 |
105 |
106 | UTTypeConformsTo
107 |
108 | public.data
109 |
110 | UTTypeDescription
111 | PLY 3D file
112 | UTTypeIdentifier
113 | com.mesh.ply
114 | UTTypeReferenceURL
115 | http://en.wikipedia.org/wiki/PLY_%28file_format%29
116 | UTTypeTagSpecification
117 |
118 | public.filename-extension
119 |
120 | ply
121 |
122 |
123 |
124 |
125 | UTTypeConformsTo
126 |
127 | public.data
128 |
129 | UTTypeDescription
130 | Stereolithography CAD model
131 | UTTypeIdentifier
132 | com.mesh.stl
133 | UTTypeReferenceURL
134 | http://en.wikipedia.org/wiki/STL_(file_format)
135 | UTTypeTagSpecification
136 |
137 | public.filename-extension
138 |
139 | stl
140 |
141 |
142 |
143 |
144 | UTTypeConformsTo
145 |
146 | public.data
147 |
148 | UTTypeDescription
149 | Geomview's polyhedral file format
150 | UTTypeIdentifier
151 | com.mesh.off
152 | UTTypeReferenceURL
153 | http://tetgen.berlios.de/fformats.off.html
154 | UTTypeTagSpecification
155 |
156 | public.filename-extension
157 |
158 | off
159 |
160 |
161 |
162 |
163 | UTTypeConformsTo
164 |
165 | public.data
166 |
167 | UTTypeDescription
168 | Virtual Reality Modeling Language
169 | UTTypeIdentifier
170 | com.mesh.wrl
171 | UTTypeReferenceURL
172 | http://en.wikipedia.org/wiki/VRML#WRL_File_Format
173 | UTTypeTagSpecification
174 |
175 | public.filename-extension
176 |
177 | wrl
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Mozilla Public License, version 2.0
2 |
3 | 1. Definitions
4 |
5 | 1.1. "Contributor"
6 |
7 | means each individual or legal entity that creates, contributes to the
8 | creation of, or owns Covered Software.
9 |
10 | 1.2. "Contributor Version"
11 |
12 | means the combination of the Contributions of others (if any) used by a
13 | Contributor and that particular Contributor's Contribution.
14 |
15 | 1.3. "Contribution"
16 |
17 | means Covered Software of a particular Contributor.
18 |
19 | 1.4. "Covered Software"
20 |
21 | means Source Code Form to which the initial Contributor has attached the
22 | notice in Exhibit A, the Executable Form of such Source Code Form, and
23 | Modifications of such Source Code Form, in each case including portions
24 | thereof.
25 |
26 | 1.5. "Incompatible With Secondary Licenses"
27 | means
28 |
29 | a. that the initial Contributor has attached the notice described in
30 | Exhibit B to the Covered Software; or
31 |
32 | b. that the Covered Software was made available under the terms of
33 | version 1.1 or earlier of the License, but not also under the terms of
34 | a Secondary License.
35 |
36 | 1.6. "Executable Form"
37 |
38 | means any form of the work other than Source Code Form.
39 |
40 | 1.7. "Larger Work"
41 |
42 | means a work that combines Covered Software with other material, in a
43 | separate file or files, that is not Covered Software.
44 |
45 | 1.8. "License"
46 |
47 | means this document.
48 |
49 | 1.9. "Licensable"
50 |
51 | means having the right to grant, to the maximum extent possible, whether
52 | at the time of the initial grant or subsequently, any and all of the
53 | rights conveyed by this License.
54 |
55 | 1.10. "Modifications"
56 |
57 | means any of the following:
58 |
59 | a. any file in Source Code Form that results from an addition to,
60 | deletion from, or modification of the contents of Covered Software; or
61 |
62 | b. any new file in Source Code Form that contains any Covered Software.
63 |
64 | 1.11. "Patent Claims" of a Contributor
65 |
66 | means any patent claim(s), including without limitation, method,
67 | process, and apparatus claims, in any patent Licensable by such
68 | Contributor that would be infringed, but for the grant of the License,
69 | by the making, using, selling, offering for sale, having made, import,
70 | or transfer of either its Contributions or its Contributor Version.
71 |
72 | 1.12. "Secondary License"
73 |
74 | means either the GNU General Public License, Version 2.0, the GNU Lesser
75 | General Public License, Version 2.1, the GNU Affero General Public
76 | License, Version 3.0, or any later versions of those licenses.
77 |
78 | 1.13. "Source Code Form"
79 |
80 | means the form of the work preferred for making modifications.
81 |
82 | 1.14. "You" (or "Your")
83 |
84 | means an individual or a legal entity exercising rights under this
85 | License. For legal entities, "You" includes any entity that controls, is
86 | controlled by, or is under common control with You. For purposes of this
87 | definition, "control" means (a) the power, direct or indirect, to cause
88 | the direction or management of such entity, whether by contract or
89 | otherwise, or (b) ownership of more than fifty percent (50%) of the
90 | outstanding shares or beneficial ownership of such entity.
91 |
92 |
93 | 2. License Grants and Conditions
94 |
95 | 2.1. Grants
96 |
97 | Each Contributor hereby grants You a world-wide, royalty-free,
98 | non-exclusive license:
99 |
100 | a. under intellectual property rights (other than patent or trademark)
101 | Licensable by such Contributor to use, reproduce, make available,
102 | modify, display, perform, distribute, and otherwise exploit its
103 | Contributions, either on an unmodified basis, with Modifications, or
104 | as part of a Larger Work; and
105 |
106 | b. under Patent Claims of such Contributor to make, use, sell, offer for
107 | sale, have made, import, and otherwise transfer either its
108 | Contributions or its Contributor Version.
109 |
110 | 2.2. Effective Date
111 |
112 | The licenses granted in Section 2.1 with respect to any Contribution
113 | become effective for each Contribution on the date the Contributor first
114 | distributes such Contribution.
115 |
116 | 2.3. Limitations on Grant Scope
117 |
118 | The licenses granted in this Section 2 are the only rights granted under
119 | this License. No additional rights or licenses will be implied from the
120 | distribution or licensing of Covered Software under this License.
121 | Notwithstanding Section 2.1(b) above, no patent license is granted by a
122 | Contributor:
123 |
124 | a. for any code that a Contributor has removed from Covered Software; or
125 |
126 | b. for infringements caused by: (i) Your and any other third party's
127 | modifications of Covered Software, or (ii) the combination of its
128 | Contributions with other software (except as part of its Contributor
129 | Version); or
130 |
131 | c. under Patent Claims infringed by Covered Software in the absence of
132 | its Contributions.
133 |
134 | This License does not grant any rights in the trademarks, service marks,
135 | or logos of any Contributor (except as may be necessary to comply with
136 | the notice requirements in Section 3.4).
137 |
138 | 2.4. Subsequent Licenses
139 |
140 | No Contributor makes additional grants as a result of Your choice to
141 | distribute the Covered Software under a subsequent version of this
142 | License (see Section 10.2) or under the terms of a Secondary License (if
143 | permitted under the terms of Section 3.3).
144 |
145 | 2.5. Representation
146 |
147 | Each Contributor represents that the Contributor believes its
148 | Contributions are its original creation(s) or it has sufficient rights to
149 | grant the rights to its Contributions conveyed by this License.
150 |
151 | 2.6. Fair Use
152 |
153 | This License is not intended to limit any rights You have under
154 | applicable copyright doctrines of fair use, fair dealing, or other
155 | equivalents.
156 |
157 | 2.7. Conditions
158 |
159 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
160 | Section 2.1.
161 |
162 |
163 | 3. Responsibilities
164 |
165 | 3.1. Distribution of Source Form
166 |
167 | All distribution of Covered Software in Source Code Form, including any
168 | Modifications that You create or to which You contribute, must be under
169 | the terms of this License. You must inform recipients that the Source
170 | Code Form of the Covered Software is governed by the terms of this
171 | License, and how they can obtain a copy of this License. You may not
172 | attempt to alter or restrict the recipients' rights in the Source Code
173 | Form.
174 |
175 | 3.2. Distribution of Executable Form
176 |
177 | If You distribute Covered Software in Executable Form then:
178 |
179 | a. such Covered Software must also be made available in Source Code Form,
180 | as described in Section 3.1, and You must inform recipients of the
181 | Executable Form how they can obtain a copy of such Source Code Form by
182 | reasonable means in a timely manner, at a charge no more than the cost
183 | of distribution to the recipient; and
184 |
185 | b. You may distribute such Executable Form under the terms of this
186 | License, or sublicense it under different terms, provided that the
187 | license for the Executable Form does not attempt to limit or alter the
188 | recipients' rights in the Source Code Form under this License.
189 |
190 | 3.3. Distribution of a Larger Work
191 |
192 | You may create and distribute a Larger Work under terms of Your choice,
193 | provided that You also comply with the requirements of this License for
194 | the Covered Software. If the Larger Work is a combination of Covered
195 | Software with a work governed by one or more Secondary Licenses, and the
196 | Covered Software is not Incompatible With Secondary Licenses, this
197 | License permits You to additionally distribute such Covered Software
198 | under the terms of such Secondary License(s), so that the recipient of
199 | the Larger Work may, at their option, further distribute the Covered
200 | Software under the terms of either this License or such Secondary
201 | License(s).
202 |
203 | 3.4. Notices
204 |
205 | You may not remove or alter the substance of any license notices
206 | (including copyright notices, patent notices, disclaimers of warranty, or
207 | limitations of liability) contained within the Source Code Form of the
208 | Covered Software, except that You may alter any license notices to the
209 | extent required to remedy known factual inaccuracies.
210 |
211 | 3.5. Application of Additional Terms
212 |
213 | You may choose to offer, and to charge a fee for, warranty, support,
214 | indemnity or liability obligations to one or more recipients of Covered
215 | Software. However, You may do so only on Your own behalf, and not on
216 | behalf of any Contributor. You must make it absolutely clear that any
217 | such warranty, support, indemnity, or liability obligation is offered by
218 | You alone, and You hereby agree to indemnify every Contributor for any
219 | liability incurred by such Contributor as a result of warranty, support,
220 | indemnity or liability terms You offer. You may include additional
221 | disclaimers of warranty and limitations of liability specific to any
222 | jurisdiction.
223 |
224 | 4. Inability to Comply Due to Statute or Regulation
225 |
226 | If it is impossible for You to comply with any of the terms of this License
227 | with respect to some or all of the Covered Software due to statute,
228 | judicial order, or regulation then You must: (a) comply with the terms of
229 | this License to the maximum extent possible; and (b) describe the
230 | limitations and the code they affect. Such description must be placed in a
231 | text file included with all distributions of the Covered Software under
232 | this License. Except to the extent prohibited by statute or regulation,
233 | such description must be sufficiently detailed for a recipient of ordinary
234 | skill to be able to understand it.
235 |
236 | 5. Termination
237 |
238 | 5.1. The rights granted under this License will terminate automatically if You
239 | fail to comply with any of its terms. However, if You become compliant,
240 | then the rights granted under this License from a particular Contributor
241 | are reinstated (a) provisionally, unless and until such Contributor
242 | explicitly and finally terminates Your grants, and (b) on an ongoing
243 | basis, if such Contributor fails to notify You of the non-compliance by
244 | some reasonable means prior to 60 days after You have come back into
245 | compliance. Moreover, Your grants from a particular Contributor are
246 | reinstated on an ongoing basis if such Contributor notifies You of the
247 | non-compliance by some reasonable means, this is the first time You have
248 | received notice of non-compliance with this License from such
249 | Contributor, and You become compliant prior to 30 days after Your receipt
250 | of the notice.
251 |
252 | 5.2. If You initiate litigation against any entity by asserting a patent
253 | infringement claim (excluding declaratory judgment actions,
254 | counter-claims, and cross-claims) alleging that a Contributor Version
255 | directly or indirectly infringes any patent, then the rights granted to
256 | You by any and all Contributors for the Covered Software under Section
257 | 2.1 of this License shall terminate.
258 |
259 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
260 | license agreements (excluding distributors and resellers) which have been
261 | validly granted by You or Your distributors under this License prior to
262 | termination shall survive termination.
263 |
264 | 6. Disclaimer of Warranty
265 |
266 | Covered Software is provided under this License on an "as is" basis,
267 | without warranty of any kind, either expressed, implied, or statutory,
268 | including, without limitation, warranties that the Covered Software is free
269 | of defects, merchantable, fit for a particular purpose or non-infringing.
270 | The entire risk as to the quality and performance of the Covered Software
271 | is with You. Should any Covered Software prove defective in any respect,
272 | You (not any Contributor) assume the cost of any necessary servicing,
273 | repair, or correction. This disclaimer of warranty constitutes an essential
274 | part of this License. No use of any Covered Software is authorized under
275 | this License except under this disclaimer.
276 |
277 | 7. Limitation of Liability
278 |
279 | Under no circumstances and under no legal theory, whether tort (including
280 | negligence), contract, or otherwise, shall any Contributor, or anyone who
281 | distributes Covered Software as permitted above, be liable to You for any
282 | direct, indirect, special, incidental, or consequential damages of any
283 | character including, without limitation, damages for lost profits, loss of
284 | goodwill, work stoppage, computer failure or malfunction, or any and all
285 | other commercial damages or losses, even if such party shall have been
286 | informed of the possibility of such damages. This limitation of liability
287 | shall not apply to liability for death or personal injury resulting from
288 | such party's negligence to the extent applicable law prohibits such
289 | limitation. Some jurisdictions do not allow the exclusion or limitation of
290 | incidental or consequential damages, so this exclusion and limitation may
291 | not apply to You.
292 |
293 | 8. Litigation
294 |
295 | Any litigation relating to this License may be brought only in the courts
296 | of a jurisdiction where the defendant maintains its principal place of
297 | business and such litigation shall be governed by laws of that
298 | jurisdiction, without reference to its conflict-of-law provisions. Nothing
299 | in this Section shall prevent a party's ability to bring cross-claims or
300 | counter-claims.
301 |
302 | 9. Miscellaneous
303 |
304 | This License represents the complete agreement concerning the subject
305 | matter hereof. If any provision of this License is held to be
306 | unenforceable, such provision shall be reformed only to the extent
307 | necessary to make it enforceable. Any law or regulation which provides that
308 | the language of a contract shall be construed against the drafter shall not
309 | be used to construe this License against a Contributor.
310 |
311 |
312 | 10. Versions of the License
313 |
314 | 10.1. New Versions
315 |
316 | Mozilla Foundation is the license steward. Except as provided in Section
317 | 10.3, no one other than the license steward has the right to modify or
318 | publish new versions of this License. Each version will be given a
319 | distinguishing version number.
320 |
321 | 10.2. Effect of New Versions
322 |
323 | You may distribute the Covered Software under the terms of the version
324 | of the License under which You originally received the Covered Software,
325 | or under the terms of any subsequent version published by the license
326 | steward.
327 |
328 | 10.3. Modified Versions
329 |
330 | If you create software not governed by this License, and you want to
331 | create a new license for such software, you may create and use a
332 | modified version of this License if you rename the license and remove
333 | any references to the name of the license steward (except to note that
334 | such modified license differs from this License).
335 |
336 | 10.4. Distributing Source Code Form that is Incompatible With Secondary
337 | Licenses If You choose to distribute Source Code Form that is
338 | Incompatible With Secondary Licenses under the terms of this version of
339 | the License, the notice described in Exhibit B of this License must be
340 | attached.
341 |
342 | Exhibit A - Source Code Form License Notice
343 |
344 | This Source Code Form is subject to the
345 | terms of the Mozilla Public License, v.
346 | 2.0. If a copy of the MPL was not
347 | distributed with this file, You can
348 | obtain one at
349 | http://mozilla.org/MPL/2.0/.
350 |
351 | If it is not possible or desirable to put the notice in a particular file,
352 | then You may include the notice in a location (such as a LICENSE file in a
353 | relevant directory) where a recipient would be likely to look for such a
354 | notice.
355 |
356 | You may add additional accurate notices of copyright ownership.
357 |
358 | Exhibit B - "Incompatible With Secondary Licenses" Notice
359 |
360 | This Source Code Form is "Incompatible
361 | With Secondary Licenses", as defined by
362 | the Mozilla Public License, v. 2.0.
363 |
364 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: all, install
2 |
3 | # Seems that we unfortunately must use llvm or else we get issues trying to
4 | # include the Foundation headers
5 | #CXX=llvm-g++
6 | #C=llvm-gcc
7 | CXX=clang++
8 | C=clang
9 | #CXX=clang++-mp-3.4
10 | #C=clang-mp-3.4
11 | CXXFLAGS += -stdlib=libc++ -std=c++11
12 |
13 | #Be sure that libs aren't used
14 | LIBIGL=/usr/local/libigl/
15 | LIBIGL_INC=-I$(LIBIGL)/include
16 | EIGEN3_INC=-I/usr/local/libigl/external/eigen
17 |
18 | # Do not use the GLU that comes with the macports Mesa:
19 | # http://www.alecjacobson.com/weblog/?p=2827
20 | GLU=/usr/local/
21 | GLU_INC=-I$(GLU)/include
22 | #GLU_LIB=-L$(GLU)/lib -lGLU
23 | GLU_LIB=$(GLU)/lib/libGLU.a
24 |
25 | MESA=/usr/local/Cellar/mesalib-glw/8.0.0/
26 | MESA_INC=-I$(MESA)/include
27 | MESA_LIB=-L$(MESA)/lib -lOSMesa -lGL
28 |
29 | OBJC_LIB=-lobjc
30 |
31 | all: obj Mesh.qlgenerator
32 | deploy:
33 | dylibbundler -od -b -x ./Mesh.qlgenerator/Contents/MacOS/Mesh -d ./Mesh.qlgenerator/Contents/libs -p @loader_path/../libs/
34 | install:
35 | rm -rf /Library/QuickLook/Mesh.qlgenerator
36 | cp -R Mesh.qlgenerator /Library/QuickLook/Mesh.qlgenerator
37 | qlmanage -r
38 | qlmanage -r cache
39 |
40 | #CFLAGS += -Wall -g -O0
41 | # openmp is unfortunately not supported by llvm
42 | CFLAGS += -O3 -Wall -DNDEBUG -Winvalid-pch -m64 -msse4.2
43 | OBJCFLAGS += -O3 -Wall -DNDEBUG -Winvalid-pch -m64 -msse4.2
44 |
45 | CPP_FILES=$(wildcard src/*.cpp)
46 | C_FILES=$(wildcard src/*.c)
47 | M_FILES=$(wildcard src/*.m)
48 | OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) \
49 | $(addprefix obj/,$(notdir $(M_FILES:.m=.o))) \
50 | $(addprefix obj/,$(notdir $(C_FILES:.c=.o)))
51 |
52 | LIB+=$(LIBIGL_LIB) $(GLU_LIB) $(MESA_LIB) $(OBJC_LIB) -framework Foundation \
53 | -framework AppKit -framework QuickLook -lc++
54 | INC+=$(EIGEN3_INC) $(LIBIGL_INC) $(GLU_INC) $(MESA_INC)
55 |
56 | .PHONY:
57 |
58 | Mesh.qlgenerator: Mesh.qlgenerator/Contents/MacOS/ \
59 | Mesh.qlgenerator/Contents/Resources/ \
60 | Mesh.qlgenerator/Contents/MacOS/Mesh \
61 | Mesh.qlgenerator/Contents/Info.plist
62 |
63 | Mesh.qlgenerator/Contents/Info.plist: Info.plist
64 | cp Info.plist Mesh.qlgenerator/Contents/Info.plist
65 |
66 | Mesh.qlgenerator/Contents/MacOS/:
67 | mkdir -p $@
68 |
69 | Mesh.qlgenerator/Contents/Resources/:
70 | mkdir -p $@
71 |
72 | Mesh.qlgenerator/Contents/MacOS/Mesh: $(OBJ_FILES)
73 | ${CXX} $(CFLAGS) $(CXXFLAGS) -bundle -o $@ $(OBJ_FILES) $(LIB)
74 | #dylibbundler -od -b -x ./Mesh.qlgenerator/Contents/MacOS/Mesh -d ./Mesh.qlgenerator/Contents/libs/
75 |
76 | obj:
77 | mkdir -p obj
78 |
79 | obj/%.o: src/%.cpp src/%.h
80 | ${CXX} $(CFLAGS) $(CXXFLAGS) -o $@ -c $< $(INC)
81 |
82 | obj/%.o: src/%.m
83 | ${CXX} $(OBJCFLAGS) -o $@ -c $< $(INC)
84 |
85 | obj/%.o: src/%.c
86 | ${C} $(CFLAGS) -o $@ -c $< $(INC)
87 |
88 | clean:
89 | rm -f $(OBJ_FILES)
90 | rm -rf Mesh.qlgenerator
91 |
--------------------------------------------------------------------------------
/Mesh.qlgenerator/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 13E28
7 | CFBundleDevelopmentRegion
8 | English
9 | CFBundleDocumentTypes
10 |
11 |
12 | CFBundleTypeRole
13 | QLGenerator
14 | LSItemContentTypes
15 |
16 | public.3d-content
17 | com.mesh.mesh
18 | com.mesh.off
19 | com.mesh.ply
20 | com.mesh.stl
21 | com.mesh.wrl
22 |
23 |
24 |
25 | CFBundleExecutable
26 | Mesh
27 | CFBundleIdentifier
28 | com.mesh.quicklook
29 | CFBundleInfoDictionaryVersion
30 | 6.0
31 | CFBundleName
32 | Mesh
33 | CFBundleShortVersionString
34 | 1.0.2
35 | CFBundleVersion
36 | 1.0
37 | CFPlugInDynamicRegisterFunction
38 |
39 | CFPlugInDynamicRegistration
40 | NO
41 | CFPlugInFactories
42 |
43 | 8D269336-626C-4F43-903F-D2F6AE5C4976
44 | QuickLookGeneratorPluginFactory
45 |
46 | CFPlugInTypes
47 |
48 | 5E2D9680-5022-40FA-B806-43349622E5B9
49 |
50 | 8D269336-626C-4F43-903F-D2F6AE5C4976
51 |
52 |
53 | CFPlugInUnloadFunction
54 |
55 | DTCompiler
56 | com.apple.compilers.llvm.clang.1_0
57 | DTPlatformBuild
58 | 5B1008
59 | DTPlatformVersion
60 | GM
61 | DTSDKBuild
62 | 13C64
63 | DTSDKName
64 | macosx10.9
65 | DTXcode
66 | 0511
67 | DTXcodeBuild
68 | 5B1008
69 | LSApplicationCategoryType
70 |
71 | NSHumanReadableCopyright
72 | Copyright © 2015 Alec Jacobson
73 | QLNeedsToBeRunInMainThread
74 |
75 | QLPreviewHeight
76 | 405
77 | QLPreviewWidth
78 | 720
79 | QLSupportsConcurrentRequests
80 |
81 | QLThumbnailMinimumSize
82 | 10
83 | UTExportedTypeDeclarations
84 |
85 |
86 |
87 | UTTypeConformsTo
88 |
89 | public.data
90 |
91 | UTTypeDescription
92 | 3d tetrahedral mesh
93 | UTTypeIdentifier
94 | com.mesh.mesh
95 | UTTypeReferenceURL
96 | http://www.ann.jussieu.fr/frey/publications/RT-0253.pdf#page=33
97 | UTTypeTagSpecification
98 |
99 | public.filename-extension
100 |
101 | mesh
102 |
103 |
104 |
105 |
106 | UTTypeConformsTo
107 |
108 | public.data
109 |
110 | UTTypeDescription
111 | PLY 3D file
112 | UTTypeIdentifier
113 | com.mesh.ply
114 | UTTypeReferenceURL
115 | http://en.wikipedia.org/wiki/PLY_%28file_format%29
116 | UTTypeTagSpecification
117 |
118 | public.filename-extension
119 |
120 | ply
121 |
122 |
123 |
124 |
125 | UTTypeConformsTo
126 |
127 | public.data
128 |
129 | UTTypeDescription
130 | Stereolithography CAD model
131 | UTTypeIdentifier
132 | com.mesh.stl
133 | UTTypeReferenceURL
134 | http://en.wikipedia.org/wiki/STL_(file_format)
135 | UTTypeTagSpecification
136 |
137 | public.filename-extension
138 |
139 | stl
140 |
141 |
142 |
143 |
144 | UTTypeConformsTo
145 |
146 | public.data
147 |
148 | UTTypeDescription
149 | Geomview's polyhedral file format
150 | UTTypeIdentifier
151 | com.mesh.off
152 | UTTypeReferenceURL
153 | http://tetgen.berlios.de/fformats.off.html
154 | UTTypeTagSpecification
155 |
156 | public.filename-extension
157 |
158 | off
159 |
160 |
161 |
162 |
163 | UTTypeConformsTo
164 |
165 | public.data
166 |
167 | UTTypeDescription
168 | Virtual Reality Modeling Language
169 | UTTypeIdentifier
170 | com.mesh.wrl
171 | UTTypeReferenceURL
172 | http://en.wikipedia.org/wiki/VRML#WRL_File_Format
173 | UTTypeTagSpecification
174 |
175 | public.filename-extension
176 |
177 | wrl
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
--------------------------------------------------------------------------------
/Mesh.qlgenerator/Contents/MacOS/Mesh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alecjacobson/MeshQuickLookPlugin/17336a72052034d4008801571d687fd46129e964/Mesh.qlgenerator/Contents/MacOS/Mesh
--------------------------------------------------------------------------------
/Mesh.qlgenerator/Contents/libs/libGL.1.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alecjacobson/MeshQuickLookPlugin/17336a72052034d4008801571d687fd46129e964/Mesh.qlgenerator/Contents/libs/libGL.1.dylib
--------------------------------------------------------------------------------
/Mesh.qlgenerator/Contents/libs/libOSMesa.8.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alecjacobson/MeshQuickLookPlugin/17336a72052034d4008801571d687fd46129e964/Mesh.qlgenerator/Contents/libs/libOSMesa.8.dylib
--------------------------------------------------------------------------------
/Mesh.qlgenerator/Contents/libs/libX11-xcb.1.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alecjacobson/MeshQuickLookPlugin/17336a72052034d4008801571d687fd46129e964/Mesh.qlgenerator/Contents/libs/libX11-xcb.1.dylib
--------------------------------------------------------------------------------
/Mesh.qlgenerator/Contents/libs/libX11.6.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alecjacobson/MeshQuickLookPlugin/17336a72052034d4008801571d687fd46129e964/Mesh.qlgenerator/Contents/libs/libX11.6.dylib
--------------------------------------------------------------------------------
/Mesh.qlgenerator/Contents/libs/libXau.6.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alecjacobson/MeshQuickLookPlugin/17336a72052034d4008801571d687fd46129e964/Mesh.qlgenerator/Contents/libs/libXau.6.dylib
--------------------------------------------------------------------------------
/Mesh.qlgenerator/Contents/libs/libXdmcp.6.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alecjacobson/MeshQuickLookPlugin/17336a72052034d4008801571d687fd46129e964/Mesh.qlgenerator/Contents/libs/libXdmcp.6.dylib
--------------------------------------------------------------------------------
/Mesh.qlgenerator/Contents/libs/libXext.6.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alecjacobson/MeshQuickLookPlugin/17336a72052034d4008801571d687fd46129e964/Mesh.qlgenerator/Contents/libs/libXext.6.dylib
--------------------------------------------------------------------------------
/Mesh.qlgenerator/Contents/libs/libxcb.1.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alecjacobson/MeshQuickLookPlugin/17336a72052034d4008801571d687fd46129e964/Mesh.qlgenerator/Contents/libs/libxcb.1.dylib
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is a small application which builds a "QuickLook generator" for Mac OS.
2 | This will generate previews (selecting a file in Finder and hitting space) and
3 | thumbnails ("Cover flow" view in Finder) for .obj, .off and .mesh 3D model
4 | files.
5 |
6 | Using [libigl][1] and Mesa3D's off screen rendering is was easy to whip up a
7 | QuickLook preview and thumbnail generator for our favorite 3D model file
8 | formats. I opted to avoid Xcode and compile the application using a good old
9 | Makefile. You can find the project in the libigl examples
10 | `libigl/examples/quicklook-mesh/` (as of version 0.3.2).
11 |
12 | Once installed the QuickLook generator will make (static) previews of any
13 | .mesh, .off, .obj or .wrl files when hit [space] after selecting the file in
14 | Finder.app.
15 |
16 | ![Mesh quicklook preview][2]
17 |
18 | Or when you use one of the fancier Finder.app views
19 |
20 | ![Mesh quicklook thumbnail][3]
21 |
22 | I imagine I'll be perfecting this over time, but for now it shows 6 canonical
23 | views and uses a double-sided material to give you an idea of any inconsistent
24 | mesh orientation issues. It should work for triangle meshes or general
25 | polygonal meshes.
26 |
27 | # Binary
28 |
29 | You can skip compiling and just install the included binary, Mesh.qlgenerator. Install it by
30 | moving `Mesh.qlgenerator/` into `/Library/QuickLook/`. Then either restart you
31 | computer or issue in a Terminal:
32 |
33 | qlmanage -r
34 | qlmanage -r cache
35 |
36 | # Binary
37 |
38 | Included in this repository is a statically compiled, ready-to-use binary
39 |
40 | # Build
41 |
42 | To build issue:
43 |
44 | make
45 |
46 | This will compile the source and build the application in ./Mesh.qlgenerator/
47 |
48 | To install issue:
49 |
50 | sudo make install
51 |
52 | This will copy the directory ./Mesh.qlgenerator/ into /Library/QuickLook/ and
53 | reload the Quicklook Manager (so that you see your changes in Finder).
54 |
55 | # Dependencies
56 |
57 | This plugin depends heavily on [libigl][1]
58 |
59 | Install Mesa3D. For example, using macports:
60 |
61 | sudo port install mesa
62 |
63 | Then re-install GLU à la http://www.alecjacobson.com/weblog/?p=2827
64 |
65 | ## Note about Mesa
66 |
67 | If things look weird (too far away, blank, etc.) then maybe you should
68 | reinstall GLU. It seems that the version of GLU that comes with macports' mesa
69 | is buggy/corrupted.
70 |
71 | # Testing
72 |
73 | After installing you can test previews with:
74 |
75 | /usr/bin/qlmanage -p ../shared/cheburashka.off
76 |
77 | and thumbnails with:
78 |
79 | /usr/bin/qlmanage -t ../shared/cheburashka.off
80 |
81 | [1]: https://github.com/libigl/libigl/
82 | [2]: http://alecjacobson.com/weblog/media/mesh-quicklook-preview-hand.jpg
83 | [3]: http://alecjacobson.com/weblog/media/mesh-quicklook-thumbnail-cover-flow.jpg
84 |
--------------------------------------------------------------------------------
/src/GeneratePreviewForURL.m:
--------------------------------------------------------------------------------
1 | // Adapted from QuickLook-pfm-master/src/GeneratePreviewForURL.m by Andreas
2 | // Steinel (https://github.com/lnxbil/quicklook-pfm)
3 | #import
4 | #import
5 | #import
6 | #import
7 | #import
8 |
9 | #include "render_to_buffer.h"
10 |
11 | // Generate a preview of a given file.
12 | OSStatus GeneratePreviewForURL(
13 | void *thisInterface,
14 | QLPreviewRequestRef preview,
15 | CFURLRef url,
16 | CFStringRef contentTypeUTI,
17 | CFDictionaryRef options)
18 | {
19 | if (QLPreviewRequestIsCancelled(preview))
20 | return noErr;
21 |
22 | NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
23 |
24 | CFStringRef file = CFURLCopyFileSystemPath(url,kCFURLPOSIXPathStyle);
25 | if (QLPreviewRequestIsCancelled(preview))
26 | return noErr;
27 | // http://stackoverflow.com/a/3797923/148668
28 | // Multi-sampling for anti-aliasing.
29 | const double MS = 2;
30 | const int width = 720;
31 | const int height = 405;
32 | const int bwidth = MS*width;
33 | const int bheight = MS*height;
34 | const int bchannels = 4;
35 | UInt8 buffer[bwidth * bheight * bchannels];
36 |
37 | const char *cs = CFStringGetCStringPtr( file, CFStringGetSystemEncoding()) ;
38 | char cs_buf[1024];
39 | // http://stackoverflow.com/a/1609664/148668
40 | if(cs == NULL)
41 | {
42 | CFStringGetCString(
43 | file,
44 | cs_buf,
45 | [(NSString*)file length]+1,
46 | kCFStringEncodingUTF8);
47 | cs = cs_buf;
48 | }
49 |
50 | const float TRANSPARENT_BLACK[4] = {0,0,0,0};
51 | render_to_buffer(cs,TRANSPARENT_BLACK,bwidth,bheight,buffer);
52 | CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
53 | CFDataRef rgbData = CFDataCreate(NULL, buffer, bwidth * bheight * 4);
54 | CGDataProviderRef provider = CGDataProviderCreateWithCFData(rgbData);
55 | // http://forum.sparrow-framework.org/topic/create-uiimage-from-pixel-data-problems
56 | CGImageRef image =
57 | CGImageCreate(
58 | bwidth,
59 | bheight,
60 | 8,
61 | 8*4,
62 | bwidth * 4,
63 | colorspace,
64 | kCGBitmapByteOrderDefault|kCGImageAlphaPremultipliedLast,
65 | provider,
66 | NULL,
67 | true,
68 | kCGRenderingIntentDefault);
69 | CFRelease(rgbData);
70 | CGDataProviderRelease(provider);
71 | CGColorSpaceRelease(colorspace);
72 | NSSize size = {width,height};
73 |
74 | if (QLPreviewRequestIsCancelled(preview))
75 | return noErr;
76 |
77 | // Draw onto context as textured rectangle
78 | CGContextRef cgContext = QLPreviewRequestCreateContext(preview, *(CGSize *)&size, true, NULL);
79 | CGRect rect = CGRectMake(0,0, width, height);
80 | CGContextDrawImage(cgContext, rect, image);
81 | QLPreviewRequestFlushContext(preview, cgContext);
82 |
83 | CFRelease(cgContext);
84 | CGImageRelease(image);
85 | [pool release];
86 | return noErr;
87 | }
88 |
89 |
90 | void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview)
91 | {
92 | // implement only if supported
93 | }
94 |
95 |
--------------------------------------------------------------------------------
/src/GenerateThumbnailForURL.m:
--------------------------------------------------------------------------------
1 | // Adapted from QuickLook-pfm-master/src/GenerateThumbnailForURL.m by Andreas
2 | // Steinel (https://github.com/lnxbil/quicklook-pfm)
3 | #import
4 | #import
5 | #import
6 | #import
7 | #import
8 |
9 | #include "render_to_buffer.h"
10 |
11 | // Creates a bitmap context for ARGB images (not sure if we really need a
12 | // separate function for this... I think there should be something builtin that
13 | // works just as well)
14 | // Taken from https://github.com/lnxbil/quicklook-pfm
15 | CGContextRef CreateARGBBitmapContext (CGSize size)
16 | {
17 | CGContextRef context = NULL;
18 | CGColorSpaceRef colorSpace;
19 | void * bitmapData;
20 | int bitmapByteCount;
21 | int bitmapBytesPerRow;
22 |
23 | // Get image width, height. We'll use the entire image.
24 | size_t pixelsWide = (size_t) size.width; //CGImageGetWidth(inImage);
25 | size_t pixelsHigh = (size_t) size.height; //CGImageGetHeight(inImage);
26 |
27 | // Declare the number of bytes per row. Each pixel in the bitmap in this
28 | // example is represented by 4 bytes; 8 bits each of red, green, blue, and
29 | // alpha.
30 | bitmapBytesPerRow = (pixelsWide * 4);
31 | bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
32 |
33 | // Use the generic RGB color space.
34 | // FIXME: Das verstehe ich net. Die Doku sagt nicht, dass es Deprecated ist und
35 | // gibt auch keine Auswahlmöglichkeit an :-(
36 | colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
37 | if (colorSpace == NULL)
38 | {
39 | NSLog(@"Error allocating color space\n");
40 | return NULL;
41 | }
42 |
43 | // Allocate memory for image data. This is the destination in memory
44 | // where any drawing to the bitmap context will be rendered.
45 | bitmapData = malloc( bitmapByteCount );
46 | if (bitmapData == NULL)
47 | {
48 | NSLog(@"Memory not allocated!");
49 | CGColorSpaceRelease( colorSpace );
50 | return NULL;
51 | }
52 |
53 | // Create the bitmap context. We want pre-multiplied ARGB, 8-bits
54 | // per component. Regardless of what the source image format is
55 | // (CMYK, Grayscale, and so on) it will be converted over to the format
56 | // specified here by CGBitmapContextCreate.
57 | context = CGBitmapContextCreate (bitmapData,
58 | pixelsWide,
59 | pixelsHigh,
60 | 8, // bits per component
61 | bitmapBytesPerRow,
62 | colorSpace,
63 | kCGBitmapByteOrderDefault|kCGImageAlphaPremultipliedLast);
64 | if (context == NULL)
65 | {
66 | free (bitmapData);
67 | NSLog(@"Context not created!");
68 | }
69 |
70 | // Make sure and release colorspace before returning
71 | CGColorSpaceRelease( colorSpace );
72 |
73 | return context;
74 | }
75 |
76 |
77 |
78 |
79 | // Generate a thumbnail for a given file
80 | OSStatus GenerateThumbnailForURL(
81 | void *thisInterface,
82 | QLThumbnailRequestRef thumbnail,
83 | CFURLRef url,
84 | CFStringRef contentTypeUTI,
85 | CFDictionaryRef options,
86 | CGSize maxSize)
87 | {
88 | if (QLThumbnailRequestIsCancelled(thumbnail))
89 | return noErr;
90 |
91 | NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
92 |
93 | CFStringRef file = CFURLCopyFileSystemPath(url,kCFURLPOSIXPathStyle);
94 |
95 | if (QLThumbnailRequestIsCancelled(thumbnail))
96 | return noErr;
97 |
98 | // raw pixel data memory of 64 * 64 pixel size
99 | // http://stackoverflow.com/a/3797923/148668
100 | // Multi-sampling for anti-aliasing
101 | const double MS = 2;
102 | const int width = maxSize.width;
103 | // Widescreen aspect ratio
104 | const int height = (270./460.)*maxSize.height;
105 | const int bwidth = MS*width;
106 | const int bheight = MS*height;
107 | const int bchannels = 4;
108 | UInt8 buffer[bwidth * bheight * bchannels];
109 | const char *cs = CFStringGetCStringPtr( file, CFStringGetSystemEncoding()) ;
110 | char cs_buf[1024];
111 | // http://stackoverflow.com/a/1609664/148668
112 | if(cs == NULL)
113 | {
114 | CFStringGetCString(file, cs_buf, [(NSString*)file length]+1, kCFStringEncodingUTF8);
115 | cs = cs_buf;
116 | }
117 | const float OPAQUE_WHITE[4] = {1,1,1,1};
118 | render_to_buffer(cs,OPAQUE_WHITE,bwidth,bheight,buffer);
119 | CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
120 | CFDataRef rgbData = CFDataCreate(NULL, buffer, bwidth * bheight * 4);
121 | CGDataProviderRef provider = CGDataProviderCreateWithCFData(rgbData);
122 | // http://forum.sparrow-framework.org/topic/create-uiimage-from-pixel-data-problems
123 | CGImageRef image = CGImageCreate(
124 | bwidth,
125 | bheight,
126 | 8,
127 | 8*4,
128 | bwidth * 4,
129 | colorspace,
130 | kCGBitmapByteOrderDefault|kCGImageAlphaPremultipliedLast,
131 | provider,
132 | NULL,
133 | true,
134 | kCGRenderingIntentDefault);
135 | CFRelease(rgbData);
136 | CGDataProviderRelease(provider);
137 | CGColorSpaceRelease(colorspace);
138 | NSSize size = {width,height};
139 |
140 | if (QLThumbnailRequestIsCancelled(thumbnail))
141 | return noErr;
142 |
143 | // Draw onto context as textured rectangle
144 | CGContextRef cgctx = CreateARGBBitmapContext(size);
145 | CGRect rect = CGRectMake(0,0, width, height);
146 | CGContextClearRect(cgctx,rect);
147 | CGContextDrawImage(cgctx, rect, image);
148 | CGImageRef newCGImage = CGBitmapContextCreateImage(cgctx);
149 | CGContextRelease(cgctx);
150 |
151 | QLThumbnailRequestSetImage(thumbnail, newCGImage, NULL);
152 |
153 | // Releasing image
154 | CGImageRelease(newCGImage);
155 | [pool release];
156 | return noErr;
157 | }
158 |
159 |
160 | void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail)
161 | {
162 | // implement only if supported
163 | }
164 |
165 |
--------------------------------------------------------------------------------
/src/main.c:
--------------------------------------------------------------------------------
1 | //==============================================================================
2 | //
3 | // DO NO MODIFY THE CONTENT OF THIS FILE
4 | //
5 | // This file contains the generic CFPlug-in code necessary for your generator
6 | // To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c
7 | //
8 | //==============================================================================
9 |
10 |
11 |
12 |
13 |
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | // -----------------------------------------------------------------------------
21 | // constants
22 | // -----------------------------------------------------------------------------
23 |
24 | // Don't modify this line
25 | #define PLUGIN_ID "C00EB589-55DF-45ED-B4B8-8AFFA367CFCF"
26 |
27 | //
28 | // Below is the generic glue code for all plug-ins.
29 | //
30 | // You should not have to modify this code aside from changing
31 | // names if you decide to change the names defined in the Info.plist
32 | //
33 |
34 |
35 | // -----------------------------------------------------------------------------
36 | // typedefs
37 | // -----------------------------------------------------------------------------
38 |
39 | // The thumbnail generation function to be implemented in GenerateThumbnailForURL.c
40 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize);
41 | void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail);
42 |
43 | // The preview generation function to be implemented in GeneratePreviewForURL.c
44 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
45 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview);
46 |
47 | // The layout for an instance of QuickLookGeneratorPlugIn
48 | typedef struct __QuickLookGeneratorPluginType
49 | {
50 | void *conduitInterface;
51 | CFUUIDRef factoryID;
52 | UInt32 refCount;
53 | } QuickLookGeneratorPluginType;
54 |
55 | // -----------------------------------------------------------------------------
56 | // prototypes
57 | // -----------------------------------------------------------------------------
58 | // Forward declaration for the IUnknown implementation.
59 | //
60 |
61 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID);
62 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance);
63 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
64 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
65 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance);
66 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance);
67 |
68 | // -----------------------------------------------------------------------------
69 | // myInterfaceFtbl definition
70 | // -----------------------------------------------------------------------------
71 | // The QLGeneratorInterfaceStruct function table.
72 | //
73 | static QLGeneratorInterfaceStruct myInterfaceFtbl = {
74 | NULL,
75 | QuickLookGeneratorQueryInterface,
76 | QuickLookGeneratorPluginAddRef,
77 | QuickLookGeneratorPluginRelease,
78 | NULL,
79 | NULL,
80 | NULL,
81 | NULL
82 | };
83 |
84 |
85 | // -----------------------------------------------------------------------------
86 | // AllocQuickLookGeneratorPluginType
87 | // -----------------------------------------------------------------------------
88 | // Utility function that allocates a new instance.
89 | // You can do some initial setup for the generator here if you wish
90 | // like allocating globals etc...
91 | //
92 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID)
93 | {
94 | QuickLookGeneratorPluginType *theNewInstance;
95 |
96 | theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType));
97 | memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType));
98 |
99 | /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */
100 | theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct));
101 | memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct));
102 |
103 | /* Retain and keep an open instance refcount for each factory. */
104 | theNewInstance->factoryID = CFRetain(inFactoryID);
105 | CFPlugInAddInstanceForFactory(inFactoryID);
106 |
107 | /* This function returns the IUnknown interface so set the refCount to one. */
108 | theNewInstance->refCount = 1;
109 | return theNewInstance;
110 | }
111 |
112 | // -----------------------------------------------------------------------------
113 | // DeallocQuickLookGeneratorPluginType
114 | // -----------------------------------------------------------------------------
115 | // Utility function that deallocates the instance when
116 | // the refCount goes to zero.
117 | // In the current implementation generator interfaces are never deallocated
118 | // but implement this as this might change in the future
119 | //
120 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance)
121 | {
122 | CFUUIDRef theFactoryID;
123 |
124 | theFactoryID = thisInstance->factoryID;
125 | /* Free the conduitInterface table up */
126 | free(thisInstance->conduitInterface);
127 |
128 | /* Free the instance structure */
129 | free(thisInstance);
130 | if (theFactoryID){
131 | CFPlugInRemoveInstanceForFactory(theFactoryID);
132 | CFRelease(theFactoryID);
133 | }
134 | }
135 |
136 | // -----------------------------------------------------------------------------
137 | // QuickLookGeneratorQueryInterface
138 | // -----------------------------------------------------------------------------
139 | // Implementation of the IUnknown QueryInterface function.
140 | //
141 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv)
142 | {
143 | CFUUIDRef interfaceID;
144 |
145 | interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
146 |
147 | if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){
148 | /* If the Right interface was requested, bump the ref count,
149 | * set the ppv parameter equal to the instance, and
150 | * return good status.
151 | */
152 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL;
153 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration;
154 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL;
155 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration;
156 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance);
157 | *ppv = thisInstance;
158 | CFRelease(interfaceID);
159 | return S_OK;
160 | }else{
161 | /* Requested interface unknown, bail with error. */
162 | *ppv = NULL;
163 | CFRelease(interfaceID);
164 | return E_NOINTERFACE;
165 | }
166 | }
167 |
168 | // -----------------------------------------------------------------------------
169 | // QuickLookGeneratorPluginAddRef
170 | // -----------------------------------------------------------------------------
171 | // Implementation of reference counting for this type. Whenever an interface
172 | // is requested, bump the refCount for the instance. NOTE: returning the
173 | // refcount is a convention but is not required so don't rely on it.
174 | //
175 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance)
176 | {
177 | ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1;
178 | return ((QuickLookGeneratorPluginType*) thisInstance)->refCount;
179 | }
180 |
181 | // -----------------------------------------------------------------------------
182 | // QuickLookGeneratorPluginRelease
183 | // -----------------------------------------------------------------------------
184 | // When an interface is released, decrement the refCount.
185 | // If the refCount goes to zero, deallocate the instance.
186 | //
187 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance)
188 | {
189 | ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1;
190 | if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){
191 | DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance );
192 | return 0;
193 | }else{
194 | return ((QuickLookGeneratorPluginType*) thisInstance )->refCount;
195 | }
196 | }
197 |
198 | // -----------------------------------------------------------------------------
199 | // QuickLookGeneratorPluginFactory
200 | // -----------------------------------------------------------------------------
201 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
202 | {
203 | QuickLookGeneratorPluginType *result;
204 | CFUUIDRef uuid;
205 |
206 | /* If correct type is being requested, allocate an
207 | * instance of kQLGeneratorTypeID and return the IUnknown interface.
208 | */
209 | if (CFEqual(typeID,kQLGeneratorTypeID)){
210 | uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
211 | result = AllocQuickLookGeneratorPluginType(uuid);
212 | CFRelease(uuid);
213 | return result;
214 | }
215 | /* If the requested type is incorrect, return NULL. */
216 | return NULL;
217 | }
218 |
219 |
--------------------------------------------------------------------------------
/src/render_to_buffer.cpp:
--------------------------------------------------------------------------------
1 | // This required to get correct linking with Objective-C files
2 | extern "C" {
3 | #include "render_to_buffer.h"
4 | };
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include
29 | #include
30 |
31 | #include
32 |
33 | static int width,height;
34 | static Eigen::MatrixXd V,N;
35 | static Eigen::MatrixXi F;
36 | static Eigen::Vector3d Vmean, Vmax,Vmin;
37 | //static bool invert = false;
38 | static float background_color[4] = {0,0,0,1};
39 |
40 | // Small viewports struct for keeping track of size and camera info
41 | #define NUM_VIEWPORTS 6
42 | class AugViewport : public igl::Viewport
43 | {
44 | public:
45 | igl::Camera camera;
46 | } viewports[NUM_VIEWPORTS];
47 |
48 | // Red screen for errors
49 | void red(const int width, const int height, GLubyte * buffer)
50 | {
51 | for(int h = 0;h sx ? sy : sx);
209 | glScaled(s,s,s);
210 | glTranslated(-Vmean(0,0),-Vmean(1,0),-Vmean(2,0));
211 | // Hack. Should really just figure out max scale so that full model fits on
212 | // screen with given perspective.
213 | //const double dz_off = (dz > 2.*dy && dz > 2.*dx ? dz/2. : 0);
214 | //glTranslated(0,0,-dz_off);
215 | }
216 |
217 | void pop_object()
218 | {
219 | glPopMatrix();
220 | }
221 |
222 | void pop_scene()
223 | {
224 | glMatrixMode(GL_PROJECTION);
225 | glPopMatrix();
226 | glMatrixMode(GL_MODELVIEW);
227 | glPopMatrix();
228 | }
229 |
230 | void display()
231 | {
232 | using namespace std;
233 | using namespace igl;
234 | glClearColor(
235 | background_color[0],
236 | background_color[1],
237 | background_color[2],
238 | background_color[3]);
239 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
240 | glEnable(GL_DEPTH_TEST);
241 | glEnable(GL_NORMALIZE);
242 | glDisable(GL_CULL_FACE);
243 | glCullFace(GL_BACK);
244 |
245 | // "Flash light" attached to camera
246 | lights();
247 | // Draw for each viewport
248 | for(int vp = 0;vp > vV,vN,vTC;
369 | vector > vF,vFTC,vFN;
370 | if(ext == "obj")
371 | {
372 | // Convert extension to lower case
373 | if(!igl::readOBJ(filename,vV,vTC,vN,vF,vFTC,vFN))
374 | {
375 | cerr<<"readOBJ failed."< T.size() || F.size() == 0)
422 | {
423 | boundary_facets(T,F);
424 | }
425 | }
426 | if(vV.size() > 0)
427 | {
428 | if(!list_to_matrix(vV,V))
429 | {
430 | cerr<<"list_to_matrix failed."<= 305
473 | /* specify Z, stencil, accum sizes */
474 | ctx = OSMesaCreateContextExt( OSMESA_RGBA, 32, 0, 0, NULL );
475 | # else
476 | ctx = OSMesaCreateContext( OSMESA_RGBA, NULL );
477 | # endif
478 | if (!ctx)
479 | {
480 | fprintf(stderr,"OSMesaCreateContext failed!\n");
481 | red(width,height,buffer);
482 | return false;
483 | }
484 |
485 | /* Bind the buffer to the context and make it current */
486 | if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, width, height))
487 | {
488 | fprintf(stderr,"OSMesaMakeCurrent failed!\n");
489 | red(width,height,buffer);
490 | return false;
491 | }
492 |
493 | // Render
494 | init_viewports();
495 | reshape(width,height);
496 | display();
497 | cout<<"Display: "<<(get_seconds()-ts)<<"s"<
3 |
4 | // Inputs:
5 | // filename path to mesh
6 | // background background color
7 | // width width of image buffer
8 | // height height of image buffer
9 | // Outputs:
10 | // buffer width*height*4 buffer of bytes (should already be allocated) RGBA
11 | // Returns true only only upon success.
12 | bool render_to_buffer(
13 | const char * filename,
14 | const float *background_color,
15 | const int width,
16 | const int height,
17 | GLubyte * buffer);
18 |
--------------------------------------------------------------------------------