Archive for November, 2012

Bash script to find best number of threads for make’s -j option

Friday, November 16th, 2012

The make command lets you specify a number of processes to run commands on using the -j option. I’ve read of a heuristic to use 1.5 times the number of cores on your machine. To find out if this is true I wrote a short script:


#!/bin/bash

for i in {1..20}
do
  make clean &>/dev/null
  printf "$i  "
  t=`(time make -j$i &>/dev/null) 2>&1 | grep real | sed -e "s/real[^0-9]*//g"`
  echo "$t"
done

For my project on my iMac with an intel i7 this prints:

1  1m1.235s
2  0m32.128s
3  0m23.353s
4  0m19.989s
5  0m18.007s
6  0m16.613s
7  0m15.490s
8  0m15.644s
9  0m16.307s
10  0m16.415s
11  0m16.861s
12  0m17.535s
13  0m17.053s
14  0m17.112s
15  0m17.550s
16  0m17.267s
17  0m17.274s
18  0m17.618s
19  0m17.540s
20  0m17.653s

Obviously you could improve the accuracy of these timing by running multiple times and averaging.

Batch optimize all pdfs in Papers database

Friday, November 16th, 2012

I use Papers2 to organize the academic papers that I read. I store the Papers database on Dropbox. Currently I have quite a few papers and the size of the database is going close to my Dropbox allowance. Here’s what I did to reduce the database size by about 50% using Adobe Acrobat Pro 9:

  1. Back up using:
    zip -r Papers2.zip Papers2/
  2. In Acrobat open some PDF
  3. Select Advanced > PDF Optimizer...
  4. Set up your according to taste. I use:
    • Make compatible with: “Acrobat 5.0 and later”
    • Check Images: Downsample: “OFF”, Compression: “JPEG”, Quality: “Maximum”
    • Uncheck Fonts
    • Uncheck Transparency
    • Uncheck Discard Objects
    • Check Discard User Data: Uncheck all, except: “Discard private data of other applications” and “Discard hidden layer content and flatten visible layers”
    • Uncheck Clean up
  5. Save these settings as “camera”
  6. Close the pdf optimizer and the current PDF document
  7. Select Advanced > Document Processing > Batch Processing...
  8. Select “New sequence”
  9. Under Run commands on: choose “Selected Folder” and select your Papers2 folder
  10. Under Select output location: “Same folder as originals”
  11. Finally, select Output options... and:
    • Select Keep original filenames
    • Uncheck Fast web view
    • Check PDF Optimizer and under Settings... choose your “camera” preset.
  12. Save and hit Run sequence

CGAL intersections.h conflicts with Boolean_set_operations_2.h

Thursday, November 15th, 2012

I was trying to transform the cgal 2d polygon intersection example into an example that computes 3d triangle intersections.

This gave some typical pages of CGAL compiler errors:


In file included from /opt/local/include/CGAL/intersection_3.h:49:0,
                 from /opt/local/include/CGAL/Kernel/function_objects.h:34,
                 from /opt/local/include/CGAL/Cartesian/function_objects.h:28,
                 from /opt/local/include/CGAL/Cartesian/Cartesian_base.h:68,
                 from /opt/local/include/CGAL/Simple_cartesian.h:28,
                 from /opt/local/include/CGAL/Exact_predicates_exact_constructions_kernel.h:28,
                 from CGAL_includes.hpp:4:
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h: In instantiation of 'void CGAL::internal::intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3&, const typename Kernel::Point_3&, const typename Kernel::Point_3&, const Kernel&, std::list<typename Kernel::Point_3>&) [with Kernel = CGAL::Simple_cartesian<CGAL::Gmpq>; typename Kernel::Point_3 = CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Gmpq> >; typename R_::Point_3 = CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Gmpq> >]':
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:98:3:   Error: required from 'CGAL::Object CGAL::internal::intersection_coplanar_triangles(const typename Kernel::Triangle_3&, const typename Kernel::Triangle_3&, const Kernel&) [with Kernel = CGAL::Simple_cartesian<CGAL::Gmpq>; typename Kernel::Triangle_3 = CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Gmpq> >]'
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:136:53:   Error: required from 'CGAL::Object CGAL::internal::intersection(const typename Kernel::Triangle_3&, const typename Kernel::Triangle_3&, const Kernel&) [with Kernel = CGAL::Simple_cartesian<CGAL::Gmpq>; typename Kernel::Triangle_3 = CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Gmpq> >]'
/opt/local/include/CGAL/Kernel/function_objects.h:2535:49:   Error: required from 'CGAL::CommonKernelFunctors::Intersect_3<K>::Object_3 CGAL::CommonKernelFunctors::Intersect_3<K>::operator()(const T1&, const T2&) const [with T1 = CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Gmpq> >; T2 = CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Gmpq> >; K = CGAL::Simple_cartesian<CGAL::Gmpq>; CGAL::CommonKernelFunctors::Intersect_3<K>::Object_3 = CGAL::Object]'
/opt/local/include/CGAL/Lazy.h:1756:51:   Error: required from 'CGAL::Lazy_construction_object<LK, AC, EC>::result_type CGAL::Lazy_construction_object<LK, AC, EC>::operator()(const L1&, const L2&) const [with L1 = CGAL::Triangle_3<CGAL::Epeck>; L2 = CGAL::Triangle_3<CGAL::Epeck>; LK = CGAL::Epeck; AC = CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >; EC = CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Gmpq> >; CGAL::Lazy_construction_object<LK, AC, EC>::result_type = CGAL::Object]'
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:180:42:   Error: required from 'CGAL::Object CGAL::intersection(const CGAL::Triangle_3<R>&, const CGAL::Triangle_3<R>&) [with K = CGAL::Epeck]'
main.cpp:41:49:   Error: required from here
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:62:64: Error: error: call of overloaded 'intersection(CGAL::CartesianKernelFunctors::Construct_line_3<CGAL::Simple_cartesian<CGAL::Gmpq> >::Line_3, CGAL::CartesianKernelFunctors::Construct_line_3<CGAL::Simple_cartesian<CGAL::Gmpq> >::Line_3, const CGAL::Simple_cartesian<CGAL::Gmpq>&)' is ambiguous
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:62:64: note: candidates are:
In file included from /opt/local/include/CGAL/intersection_3_1.h:427:0,
                 from /opt/local/include/CGAL/intersection_3.h:29,
                 from /opt/local/include/CGAL/Kernel/function_objects.h:34,
                 from /opt/local/include/CGAL/Cartesian/function_objects.h:28,
                 from /opt/local/include/CGAL/Cartesian/Cartesian_base.h:68,
                 from /opt/local/include/CGAL/Simple_cartesian.h:28,
                 from /opt/local/include/CGAL/Exact_predicates_exact_constructions_kernel.h:28,
                 from CGAL_includes.hpp:4:
/opt/local/include/CGAL/Intersections_3/intersection_3_1_impl.h:200:1: Error: note: CGAL::Object CGAL::internal::intersection(const typename K::Line_3&, const typename K::Line_3&, const K&) [with K = CGAL::Simple_cartesian<CGAL::Gmpq>; typename K::Line_3 = CGAL::Line_3<CGAL::Simple_cartesian<CGAL::Gmpq> >]
In file included from CGAL_includes.hpp:11:0:
/opt/local/include/CGAL/Boolean_set_operations_2.h:904:23: Error: note: OutputIterator CGAL::intersection(InputIterator, InputIterator, OutputIterator, unsigned int) [with InputIterator = CGAL::Line_3<CGAL::Simple_cartesian<CGAL::Gmpq> >; OutputIterator = CGAL::Simple_cartesian<CGAL::Gmpq>]
In file included from /opt/local/include/CGAL/intersection_3.h:49:0,
                 from /opt/local/include/CGAL/Kernel/function_objects.h:34,
                 from /opt/local/include/CGAL/Cartesian/function_objects.h:28,
                 from /opt/local/include/CGAL/Cartesian/Cartesian_base.h:68,
                 from /opt/local/include/CGAL/Simple_cartesian.h:28,
                 from /opt/local/include/CGAL/Exact_predicates_exact_constructions_kernel.h:28,
                 from CGAL_includes.hpp:4:
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h: In instantiation of 'void CGAL::internal::intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3&, const typename Kernel::Point_3&, const typename Kernel::Point_3&, const Kernel&, std::list<typename Kernel::Point_3>&) [with Kernel = CGAL::Simple_cartesian<CGAL::Interval_nt<false> >; typename Kernel::Point_3 = CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >; typename R_::Point_3 = CGAL::Point_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >]':
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:98:3:   Error: required from 'CGAL::Object CGAL::internal::intersection_coplanar_triangles(const typename Kernel::Triangle_3&, const typename Kernel::Triangle_3&, const Kernel&) [with Kernel = CGAL::Simple_cartesian<CGAL::Interval_nt<false> >; typename Kernel::Triangle_3 = CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >]'
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:136:53:   Error: required from 'CGAL::Object CGAL::internal::intersection(const typename Kernel::Triangle_3&, const typename Kernel::Triangle_3&, const Kernel&) [with Kernel = CGAL::Simple_cartesian<CGAL::Interval_nt<false> >; typename Kernel::Triangle_3 = CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >]'
/opt/local/include/CGAL/Kernel/function_objects.h:2535:49:   Error: required from 'CGAL::CommonKernelFunctors::Intersect_3<K>::Object_3 CGAL::CommonKernelFunctors::Intersect_3<K>::operator()(const T1&, const T2&) const [with T1 = CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >; T2 = CGAL::Triangle_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >; K = CGAL::Simple_cartesian<CGAL::Interval_nt<false> >; CGAL::CommonKernelFunctors::Intersect_3<K>::Object_3 = CGAL::Object]'
/opt/local/include/CGAL/Lazy.h:385:22:   Error: required from 'CGAL::Lazy_rep_2<AC, EC, E2A, L1, L2>::Lazy_rep_2(const AC&, const EC&, const L1&, const L2&) [with AC = CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >; EC = CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Gmpq> >; E2A = CGAL::Cartesian_converter<CGAL::Simple_cartesian<CGAL::Gmpq>, CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >; L1 = CGAL::Triangle_3<CGAL::Epeck>; L2 = CGAL::Triangle_3<CGAL::Epeck>]'
/opt/local/include/CGAL/Lazy.h:1715:73:   Error: required from 'CGAL::Lazy_construction_object<LK, AC, EC>::result_type CGAL::Lazy_construction_object<LK, AC, EC>::operator()(const L1&, const L2&) const [with L1 = CGAL::Triangle_3<CGAL::Epeck>; L2 = CGAL::Triangle_3<CGAL::Epeck>; LK = CGAL::Epeck; AC = CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >; EC = CGAL::CommonKernelFunctors::Intersect_3<CGAL::Simple_cartesian<CGAL::Gmpq> >; CGAL::Lazy_construction_object<LK, AC, EC>::result_type = CGAL::Object]'
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:180:42:   Error: required from 'CGAL::Object CGAL::intersection(const CGAL::Triangle_3<R>&, const CGAL::Triangle_3<R>&) [with K = CGAL::Epeck]'
main.cpp:41:49:   Error: required from here
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:62:64: Error: error: call of overloaded 'intersection(CGAL::CartesianKernelFunctors::Construct_line_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >::Line_3, CGAL::CartesianKernelFunctors::Construct_line_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >::Line_3, const CGAL::Simple_cartesian<CGAL::Interval_nt<false> >&)' is ambiguous
/opt/local/include/CGAL/Triangle_3_Triangle_3_intersection.h:62:64: note: candidates are:
In file included from /opt/local/include/CGAL/intersection_3_1.h:427:0,
                 from /opt/local/include/CGAL/intersection_3.h:29,
                 from /opt/local/include/CGAL/Kernel/function_objects.h:34,
                 from /opt/local/include/CGAL/Cartesian/function_objects.h:28,
                 from /opt/local/include/CGAL/Cartesian/Cartesian_base.h:68,
                 from /opt/local/include/CGAL/Simple_cartesian.h:28,
                 from /opt/local/include/CGAL/Exact_predicates_exact_constructions_kernel.h:28,
                 from CGAL_includes.hpp:4:
/opt/local/include/CGAL/Intersections_3/intersection_3_1_impl.h:200:1: Error: note: CGAL::Object CGAL::internal::intersection(const typename K::Line_3&, const typename K::Line_3&, const K&) [with K = CGAL::Simple_cartesian<CGAL::Interval_nt<false> >; typename K::Line_3 = CGAL::Line_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >]
In file included from CGAL_includes.hpp:11:0:
/opt/local/include/CGAL/Boolean_set_operations_2.h:904:23: Error: note: OutputIterator CGAL::intersection(InputIterator, InputIterator, OutputIterator, unsigned int) [with InputIterator = CGAL::Line_3<CGAL::Simple_cartesian<CGAL::Interval_nt<false> > >; OutputIterator = CGAL::Simple_cartesian<CGAL::Interval_nt<false> >]
make: *** [obj/main.o] Error 1

I fixed this by making sure in the files where I include:


#include <CGAL/intersections.h>

I don’t include:


#include <CGAL/Boolean_set_operations_2.h>

Move vim’s undo files

Thursday, November 15th, 2012

vim creates little files to keep a persistent undo. The names are like:


.filename.txt.un~

The dot prefix and the tilde suffix make these files a pain to deal with in bash. Here’s how to move these files to another directory:


mv .*un\~ other_directory

Porting Marco Attene’s meshfix to mac os x

Wednesday, November 14th, 2012

Short notes on porting meshfix to mac. Follow readme.txt placing downloaded OpenNL and JMeshLib directories in the mesh fix directory [same as meshfix.cpp] When compiling JMeshLib be sure in makeconf file to change the lines:

# On 64-bit machines you need to uncomment the following line
# -DIS64BITPLATFORM

MOREFLAGS = $(OPTM) $(STRICTALIAS)

to:

MOREFLAGS = $(OPTM) $(STRICTALIAS) -DIS64BITPLATFORM

When compiling JMeshExt I separated the predicates.cxx file from tetgen’s source to make jrs_predicates.h and jrs_predicates.c. Placing them according to readme.txt. One note is that if jrs_predicates.c is to be a .c file rather than a .cpp file then you need to extern "C"{...} encapsulate the jrs_predicates.h header file or you will get Undefined symbol linker errors. Finally in JMeshExt and meshfix.cpp there are several casts of pointers to ints. This won’t compile on 64-bit machines. This similar operation was fixed in JMeshLib by the -DIS64BITPLATFORM. Thus, I’ve fixed the following files to use the j_voidint typedef defined by IS64BITPLATFORM in j_mesh.h:

JMeshExt-1.0alpha_src/src/holeFilling.cpp
meshfix.cpp

I’ve zipped up my changes and organization: download package. Then you can just issue:

cd OpenNL3.2.1/
# # You might need to do:
# export CC=`which cc`
# export CXX=`which c++`
./configure.sh
make -C build/Darwin-Release/
cd ../JMeshLib-1.2/
make
cd ../JMeshExt-1.0alpha_src/
make
cd ..
make

I imagine a very similar port could be used for Linux.

Update: I started occasionally getting runtime errors:

OpenNL should not have reached this point: file:/Users/ajx/Downloads/MeshFix/OpenNL3.2.1/src/NL/nl_superlu.c, line:223
Abort trap: 6

Seems this comes from compiling OpenNL without SuperLU support. SuperLU is fairly straightforward to install and so is following the OpenNL instructions for compiling with OpenNL support.

Making mercurial feel like svn

Sunday, November 11th, 2012

Stop asking for my password all the time

The easy way to fix this is to add your password in plain text to your .hgrc file.

The better way is to use SSH. We were currently using RhodeCode to serve up our mercurial repos but its easy to use SSH instead.

For exiting projects just change the [project]/.hg/hgrc file from:


[paths]
default = https://[hg username]@[server]/hg/[project]

to


[paths]
default = ssh://[ssh username]@[server]/hg/[project]

Notice that your [hg username] might be different from your [ssh username].

Update: I’m still figuring this one out…

One-liner commit,push and pull,update

To automatically push after every commit just add the following to your ~/.hgrc:


[hooks]
pre-commit = echo "\x1B[00;32mAutomatically pushing\x1B[00m"
commit.autopush = hg push

The echo serves as a reminder that each commit is really pushing.

To automatically update after each pull, just issue:


hg pull -u

Round images to width and heights divisible by 2, by cropping

Saturday, November 10th, 2012

To make an h264 movie from a bunch of images using ffmpeg I need all the images to have size dimensions divisible by two. Here’s a little one-liner to crop a bunch of images to the nearest size divisible by 2:


for file in *.png; do convert -crop `identify -format "(%[fx:w]/2)*2" $file | bc`x`identify -format "(%[fx:h]/2)*2" $file | bc`+0+0 $file cropped_$file; done

I suppose using mogrify would potentially be faster. But I’m not sure how to introduce the rounding.

One liner to add public key to authorized ssh keys

Monday, November 5th, 2012
cat ~/.ssh/id_rsa.pub | ssh jacobson@pascal.cs.columbia.edu 'mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys'